├── .gitignore
├── .gitreview
├── AUTHORS
├── COPYING
├── ChangeLog
├── CommonLibs
├── BitVector.cpp
├── BitVector.h
├── Interthread.h
├── LinkedLists.cpp
├── LinkedLists.h
├── Logger.cpp
├── Logger.h
├── Makefile.am
├── PRBS.h
├── Sockets.cpp
├── Sockets.h
├── Threads.cpp
├── Threads.h
├── Timeval.cpp
├── Timeval.h
├── Utils.cpp
├── Utils.h
├── Vector.h
├── config_defs.h
├── debug.c
├── debug.h
├── osmo_signal.h
├── trx_vty.c
└── trx_vty.h
├── GSM
├── GSMCommon.cpp
├── GSMCommon.h
└── Makefile.am
├── INSTALLATION
├── LEGAL
├── Makefile.am
├── Makefile.common
├── NEWS
├── README
├── Transceiver52M
├── Channelizer.cpp
├── Channelizer.h
├── ChannelizerBase.cpp
├── ChannelizerBase.h
├── Complex.h
├── Makefile.am
├── README
├── README.DFEsymbolspaced
├── Resampler.cpp
├── Resampler.h
├── Synthesis.cpp
├── Synthesis.h
├── Transceiver.cpp
├── Transceiver.h
├── arch
│ ├── Makefile.am
│ ├── arm
│ │ ├── Makefile.am
│ │ ├── convert.c
│ │ ├── convert_neon.S
│ │ ├── convolve.c
│ │ ├── convolve_neon.S
│ │ ├── mult.c
│ │ ├── mult_neon.S
│ │ ├── scale.c
│ │ └── scale_neon.S
│ ├── common
│ │ ├── Makefile.am
│ │ ├── convert.h
│ │ ├── convert_base.c
│ │ ├── convolve.h
│ │ ├── convolve_base.c
│ │ ├── fft.c
│ │ ├── fft.h
│ │ ├── mult.h
│ │ └── scale.h
│ └── x86
│ │ ├── Makefile.am
│ │ ├── convert.c
│ │ ├── convert_sse_3.c
│ │ ├── convert_sse_3.h
│ │ ├── convert_sse_4_1.c
│ │ ├── convert_sse_4_1.h
│ │ ├── convolve.c
│ │ ├── convolve_sse_3.c
│ │ └── convolve_sse_3.h
├── device
│ ├── Makefile.am
│ ├── lms
│ │ ├── LMSDevice.cpp
│ │ ├── LMSDevice.h
│ │ └── Makefile.am
│ ├── radioDevice.h
│ ├── uhd
│ │ ├── Makefile.am
│ │ └── UHDDevice.cpp
│ └── usrp1
│ │ ├── Makefile.am
│ │ ├── USRPDevice.cpp
│ │ └── USRPDevice.h
├── inband-signaling-usb
├── laurent.m
├── osmo-trx.cpp
├── pulseApproximate.m
├── radioBuffer.cpp
├── radioBuffer.h
├── radioClock.cpp
├── radioClock.h
├── radioInterface.cpp
├── radioInterface.h
├── radioInterfaceMulti.cpp
├── radioInterfaceResamp.cpp
├── radioVector.cpp
├── radioVector.h
├── sigProcLib.cpp
├── sigProcLib.h
├── signalVector.cpp
├── signalVector.h
└── std_inband.rbf
├── autogen.sh
├── config
├── ax_check_compile_flag.m4
├── ax_cxx_compile_stdcxx.m4
├── ax_cxx_compile_stdcxx_11.m4
└── ax_sse.m4
├── configure.ac
├── contrib
├── Makefile.am
├── jenkins.sh
└── systemd
│ ├── Makefile.am
│ ├── osmo-trx-lms.service
│ ├── osmo-trx-uhd.service
│ └── osmo-trx-usrp1.service
├── debian
├── changelog
├── compat
├── control
├── copyright
├── osmo-trx-lms.install
├── osmo-trx-uhd.install
├── osmo-trx-usrp1.install
├── osmo-trx.install
├── patches
│ ├── build-for-debian8.patch
│ └── series
├── rules
└── source
│ └── format
├── doc
├── Makefile.am
├── examples
│ ├── Makefile.am
│ ├── osmo-trx-lms
│ │ ├── osmo-trx-limesdr.cfg
│ │ └── osmo-trx-lms.cfg
│ └── osmo-trx-uhd
│ │ ├── osmo-trx-limesdr.cfg
│ │ ├── osmo-trx-uhd.cfg
│ │ ├── osmo-trx-umtrx.cfg
│ │ └── osmo-trx-usrp_b200.cfg
└── manuals
│ ├── Makefile.am
│ ├── chapters
│ ├── code-architecture.adoc
│ ├── configuration.adoc
│ ├── control.adoc
│ ├── counters.adoc
│ ├── counters_generated.adoc
│ ├── overview.adoc
│ ├── running.adoc
│ ├── trx-architectures.adoc
│ ├── trx-backends.adoc
│ └── trx-devices.adoc
│ ├── osmotrx-usermanual-docinfo.xml
│ ├── osmotrx-usermanual.adoc
│ ├── osmotrx-vty-reference.xml
│ └── vty
│ ├── trx_vty_additions.xml
│ └── trx_vty_reference.xml
├── git-version-gen
├── tests
├── CommonLibs
│ ├── BitVectorTest.cpp
│ ├── BitVectorTest.ok
│ ├── InterthreadTest.cpp
│ ├── InterthreadTest.ok
│ ├── LogTest.cpp
│ ├── LogTest.err
│ ├── LogTest.ok
│ ├── Makefile.am
│ ├── PRBSTest.cpp
│ ├── PRBSTest.ok
│ ├── SocketsTest.cpp
│ ├── SocketsTest.ok
│ ├── TimevalTest.cpp
│ ├── TimevalTest.ok
│ ├── VectorTest.cpp
│ └── VectorTest.ok
├── Makefile.am
├── Transceiver52M
│ ├── LMSDeviceTest.cpp
│ ├── Makefile.am
│ ├── convolve_test.c
│ ├── convolve_test.ok
│ └── convolve_test_golden.h
└── testsuite.at
└── utils
└── clockdump.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | # build results
2 | *.o
3 | *.lo
4 | *.la
5 | Transceiver52M/osmo-trx-uhd
6 | Transceiver52M/osmo-trx-usrp1
7 | Transceiver52M/osmo-trx-lms
8 |
9 | # tests
10 | tests/CommonLibs/BitVectorTest
11 | tests/CommonLibs/F16Test
12 | tests/CommonLibs/InterthreadTest
13 | tests/CommonLibs/LogTest
14 | tests/CommonLibs/RegexpTest
15 | tests/CommonLibs/SocketsTest
16 | tests/CommonLibs/TimevalTest
17 | tests/CommonLibs/URLEncodeTest
18 | tests/CommonLibs/VectorTest
19 | tests/CommonLibs/PRBSTest
20 | tests/Transceiver52M/convolve_test
21 | tests/Transceiver52M/LMSDeviceTest
22 |
23 | # automake/autoconf
24 | *.in
25 | .deps
26 | .libs
27 | .dirstamp
28 | *~
29 | Makefile
30 | config.log
31 | config.status
32 | config.h
33 | config.guess
34 | config.sub
35 | config/*
36 | configure
37 | compile
38 | aclocal.m4
39 | autom4te.cache
40 | depcomp
41 | install-sh
42 | libtool
43 | ltmain.sh
44 | missing
45 | stamp-h1
46 | INSTALL
47 | tests/package.m4
48 | tests/testsuite
49 | tests/atconfig
50 | tests/testsuite.dir
51 | tests/testsuite.log
52 |
53 | # vim
54 | *.sw?
55 |
56 | # manuals
57 | doc/manuals/*.html
58 | doc/manuals/*.svg
59 | doc/manuals/*.pdf
60 | doc/manuals/*__*.png
61 | doc/manuals/*.check
62 | doc/manuals/generated/
63 | doc/manuals/osmomsc-usermanual.xml
64 | doc/manuals/common
65 | doc/manuals/build
66 |
--------------------------------------------------------------------------------
/.gitreview:
--------------------------------------------------------------------------------
1 | [gerrit]
2 | host=gerrit.osmocom.org
3 | project=osmo-trx
4 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008, 2009 Free Software Foundation, Inc.
3 | #
4 | # This file is part of GNU Radio
5 | #
6 | # GNU Radio is free software; you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation; either version 3, or (at your option)
9 | # any later version.
10 | #
11 | # GNU Radio is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License along
17 | # with this program; if not, write to the Free Software Foundation, Inc.,
18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 | #
20 |
21 | David A. Burgess, dburgess@kestrelsp.com:
22 | CLI/CLI.cpp
23 | CLI/CLI.h
24 | CommonLibs/Assert.h
25 | CommonLibs/BitVector.cpp
26 | CommonLibs/Interthread.h
27 | CommonLibs/LinkedLists.cpp
28 | CommonLibs/LinkedLists.h
29 | CommonLibs/Regexp.h
30 | CommonLibs/Sockets.cpp
31 | CommonLibs/Sockets.h
32 | CommonLibs/Threads.cpp
33 | CommonLibs/Threads.h
34 | CommonLibs/Timeval.cpp
35 | CommonLibs/Timeval.h
36 | CommonLibs/Vector.h
37 | GSM/GSM610Tables.cpp
38 | GSM/GSM610Tables.h
39 | GSM/GSMCommon.cpp
40 | GSM/GSMCommon.h
41 | GSM/GSMConfig.h
42 | GSM/GSML1FEC.cpp
43 | GSM/GSML1FEC.h
44 | GSM/GSML2LAPDm.cpp
45 | GSM/GSML2LAPDm.h
46 | GSM/GSML3CCElements.cpp
47 | GSM/GSML3CCElements.h
48 | GSM/GSML3CCMessages.cpp
49 | GSM/GSML3CCMessages.h
50 | GSM/GSML3CommonElements.cpp
51 | GSM/GSML3CommonElements.h
52 | GSM/GSML3MMElements.cpp
53 | GSM/GSML3MMElements.h
54 | GSM/GSML3MMMessages.cpp
55 | GSM/GSML3MMMessages.h
56 | GSM/GSML3Message.cpp
57 | GSM/GSML3Message.h
58 | GSM/GSML3RRElements.cpp
59 | GSM/GSML3RRElements.h
60 | GSM/GSML3RRMessages.cpp
61 | GSM/GSML3RRMessages.h
62 | GSM/GSMLogicalChannel.h
63 | GSM/GSMTDMA.cpp
64 | GSM/GSMTDMA.h
65 | GSM/GSMTransfer.cpp
66 | GSM/GSMTransfer.h
67 | LICENSEBLOCK
68 | TRXManager/TRXManager.cpp
69 | Transceiver/Complex.h
70 | tests/CommonLibs/BitVectorTest.cpp
71 | tests/CommonLibs/InterthreadTest.cpp
72 | tests/CommonLibs/SocketsTest.cpp
73 | tests/CommonLibs/TimevalTest.cpp
74 | tests/CommonLibs/VectorTest.cpp
75 |
76 | Harvind S. Samra, hssamra@kestrelsp.com:
77 | GSM/GSMConfig.h
78 | GSM/GSMTransfer.h
79 | LICENSEBLOCK
80 | Transceiver/ComplexTest.cpp
81 | Transceiver/Transceiver.cpp
82 | Transceiver/Transceiver.h
83 | Transceiver/USRPDevice.cpp
84 | Transceiver/USRPDevice.h
85 | Transceiver/USRPping.cpp
86 | Transceiver/radioInterface.cpp
87 | Transceiver/radioInterface.h
88 | Transceiver/rcvLPF_651.h
89 | Transceiver/runTransceiver.cpp
90 | Transceiver/sendLPF_961.h
91 | Transceiver/sigProcLib.cpp
92 | Transceiver/sigProcLib.h
93 | Transceiver/sigProcLibTest.cpp
94 | Transceiver/sweepGenerator.cpp
95 | Transceiver/testRadio.cpp
96 |
97 | Raffi Sevlian, raffisev@gmail.com:
98 | GSM/GSMCommon.h
99 | GSM/GSMConfig.h
100 | GSM/GSML1FEC.h
101 | GSM/GSML3CCElements.cpp
102 | GSM/GSML3CCElements.h
103 | GSM/GSML3CCMessages.cpp
104 | GSM/GSML3CCMessages.h
105 | GSM/GSML3CommonElements.cpp
106 | GSM/GSML3CommonElements.h
107 | GSM/GSML3MMElements.cpp
108 | GSM/GSML3MMElements.h
109 | GSM/GSML3MMMessages.cpp
110 | GSM/GSML3MMMessages.h
111 | GSM/GSML3Message.cpp
112 | GSM/GSML3Message.h
113 | GSM/GSML3RRElements.cpp
114 | GSM/GSML3RRElements.h
115 | GSM/GSML3RRMessages.cpp
116 | GSM/GSML3RRMessages.h
117 | GSM/GSMLogicalChannel.h
118 | GSM/GSMSAPMux.cpp
119 | GSM/GSMSAPMux.h
120 | GSM/GSMTransfer.h
121 | LICENSEBLOCK
122 | TRXManager/TRXManager.h
123 |
124 | Alon Levy, alonlevy1@gmail.com
125 | RRLPMessages.cpp
126 | RRLPMessages.h
127 | RRLPTest.cpp
128 |
--------------------------------------------------------------------------------
/ChangeLog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttsou/osmo-trx/5e6f3e0cadf7859ae90073cd07afec550892a448/ChangeLog
--------------------------------------------------------------------------------
/CommonLibs/LinkedLists.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 |
27 |
28 |
29 | #include "LinkedLists.h"
30 |
31 |
32 | PointerFIFO::~PointerFIFO()
33 | {
34 | ListNode *node, *next;
35 |
36 | node = mHead;
37 | while (node != NULL) {
38 | next = node->next();
39 | delete node;
40 | node = next;
41 | }
42 |
43 | node = mFreeList;
44 | while (node != NULL) {
45 | next = node->next();
46 | delete node;
47 | node = next;
48 | }
49 | }
50 |
51 | void PointerFIFO::push_front(void* val) // by pat
52 | {
53 | // Pat added this routine for completeness, but never used or tested.
54 | // The first person to use this routine should remove this assert.
55 | ListNode *node = allocate();
56 | node->data(val);
57 | node->next(mHead);
58 | mHead = node;
59 | if (!mTail) mTail=node;
60 | mSize++;
61 | }
62 |
63 | void PointerFIFO::put(void* val)
64 | {
65 | ListNode *node = allocate();
66 | node->data(val);
67 | node->next(NULL);
68 | if (mTail!=NULL) mTail->next(node);
69 | mTail=node;
70 | if (mHead==NULL) mHead=node;
71 | mSize++;
72 | }
73 |
74 | /** Take an item from the FIFO. */
75 | void* PointerFIFO::get()
76 | {
77 | // empty list?
78 | if (mHead==NULL) return NULL;
79 | // normal case
80 | ListNode* next = mHead->next();
81 | void* retVal = mHead->data();
82 | release(mHead);
83 | mHead = next;
84 | if (next==NULL) mTail=NULL;
85 | mSize--;
86 | return retVal;
87 | }
88 |
89 |
90 | ListNode *PointerFIFO::allocate()
91 | {
92 | if (mFreeList==NULL) return new ListNode;
93 | ListNode* retVal = mFreeList;
94 | mFreeList = mFreeList->next();
95 | return retVal;
96 | }
97 |
98 | void PointerFIFO::release(ListNode* wNode)
99 | {
100 | wNode->next(mFreeList);
101 | mFreeList = wNode;
102 | }
103 |
--------------------------------------------------------------------------------
/CommonLibs/Logger.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 sysmocom - s.f.m.c. GmbH
3 | *
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include // For gettimeofday
32 |
33 | #include "Logger.h"
34 | #include "Threads.h" // pat added
35 |
36 | using namespace std;
37 |
38 | Mutex gLogToLock;
39 |
40 | std::ostream& operator<<(std::ostream& os, std::ostringstream& ss)
41 | {
42 | return os << ss.str();
43 | }
44 |
45 | Log::~Log()
46 | {
47 | int old_state;
48 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
49 | int mlen = mStream.str().size();
50 | int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
51 | const char *fmt = neednl ? "%s\n" : "%s";
52 | ScopedLock lock(gLogToLock);
53 | // The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
54 | // so just use std::cout.
55 | LOGPSRC(mCategory, mPriority, filename, line, fmt, mStream.str().c_str());
56 | pthread_setcancelstate(old_state, NULL);
57 | }
58 |
59 | ostringstream& Log::get()
60 | {
61 | return mStream;
62 | }
63 |
64 | // vim: ts=4 sw=4
65 |
--------------------------------------------------------------------------------
/CommonLibs/Logger.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009, 2010 Free Software Foundation, Inc.
3 | * Copyright 2010 Kestrel Signal Processing, Inc.
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 | #ifndef LOGGER_H
27 | #define LOGGER_H
28 |
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | extern "C" {
35 | #include
36 | #include "debug.h"
37 | }
38 |
39 | /* Translation for old log statements */
40 | #ifndef LOGL_ALERT
41 | #define LOGL_ALERT LOGL_FATAL
42 | #endif
43 | #ifndef LOGL_ERR
44 | #define LOGL_ERR LOGL_ERROR
45 | #endif
46 | #ifndef LOGL_WARNING
47 | #define LOGL_WARNING LOGL_NOTICE
48 | #endif
49 |
50 | #define LOG(level) \
51 | Log(DMAIN, LOGL_##level, __BASE_FILE__, __LINE__).get() << "[tid=" << pthread_self() << "] "
52 |
53 | #define LOGC(category, level) \
54 | Log(category, LOGL_##level, __BASE_FILE__, __LINE__).get() << "[tid=" << pthread_self() << "] "
55 |
56 | #define LOGLV(category, level) \
57 | Log(category, level, __BASE_FILE__, __LINE__).get() << "[tid=" << pthread_self() << "] "
58 |
59 | /**
60 | A C++ stream-based thread-safe logger.
61 | This object is NOT the global logger;
62 | every log record is an object of this class.
63 | */
64 | class Log {
65 |
66 | public:
67 |
68 | protected:
69 |
70 | std::ostringstream mStream; ///< This is where we buffer up the log entry.
71 | int mCategory; ///< Priority of current report.
72 | int mPriority; ///< Category of current report.
73 | const char *filename; ///< Source File Name of current report.
74 | int line; ///< Line number in source file of current report.
75 |
76 | public:
77 |
78 | Log(int wCategory, int wPriority, const char* filename, int line)
79 | : mCategory(wCategory), mPriority(wPriority),
80 | filename(filename), line(line)
81 | { }
82 |
83 | // Most of the work is in the destructor.
84 | /** The destructor actually generates the log entry. */
85 | ~Log();
86 |
87 | std::ostringstream& get();
88 | };
89 |
90 | std::ostream& operator<<(std::ostream& os, std::ostringstream& ss);
91 |
92 | #endif
93 |
94 | // vim: ts=4 sw=4
95 |
--------------------------------------------------------------------------------
/CommonLibs/Makefile.am:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008, 2009 Free Software Foundation, Inc.
3 | # Copyright 2011, 2012 Range Networks, Inc.
4 | #
5 | # This software is distributed under the terms of the GNU Public License.
6 | # See the COPYING file in the main directory for details.
7 | #
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 | #
21 |
22 | include $(top_srcdir)/Makefile.common
23 |
24 | AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
25 | AM_CXXFLAGS = -Wall -O3 -g -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS)
26 | AM_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS)
27 |
28 | noinst_LTLIBRARIES = libcommon.la
29 |
30 | libcommon_la_SOURCES = \
31 | BitVector.cpp \
32 | LinkedLists.cpp \
33 | Sockets.cpp \
34 | Threads.cpp \
35 | Timeval.cpp \
36 | Logger.cpp \
37 | Utils.cpp \
38 | trx_vty.c \
39 | debug.c
40 | libcommon_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOVTY_LIBS)
41 |
42 | noinst_HEADERS = \
43 | BitVector.h \
44 | PRBS.h \
45 | Interthread.h \
46 | LinkedLists.h \
47 | Sockets.h \
48 | Threads.h \
49 | Timeval.h \
50 | Vector.h \
51 | Logger.h \
52 | Utils.h \
53 | trx_vty.h \
54 | debug.h \
55 | osmo_signal.h \
56 | config_defs.h
57 |
--------------------------------------------------------------------------------
/CommonLibs/PRBS.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 Alexander Chemeris
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public
15 | * License along with this library; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | #ifndef PRBS_H
20 | #define PRBS_H
21 |
22 | #include
23 | #include
24 |
25 | /** Pseudo-random binary sequence (PRBS) generator (a Galois LFSR implementation). */
26 | class PRBS {
27 | public:
28 |
29 | PRBS(unsigned wLen, uint64_t wCoeff, uint64_t wState = 0x01)
30 | : mCoeff(wCoeff), mStartState(wState), mState(wState), mLen(wLen)
31 | { assert(wLen<=64); }
32 |
33 | /**@name Accessors */
34 | //@{
35 | uint64_t coeff() const { return mCoeff; }
36 | uint64_t state() const { return mState; }
37 | void state(uint64_t state) { mState = state & mask(); }
38 | unsigned size() const { return mLen; }
39 | //@}
40 |
41 | /**
42 | Calculate one bit of a PRBS
43 | */
44 | unsigned generateBit()
45 | {
46 | const unsigned result = mState & 0x01;
47 | processBit(result);
48 | return result;
49 | }
50 |
51 | /**
52 | Update the generator state by one bit.
53 | If you want to synchronize your PRBS to a known state, call this function
54 | size() times passing your PRBS to it bit by bit.
55 | */
56 | void processBit(unsigned inBit)
57 | {
58 | mState >>= 1;
59 | if (inBit) mState ^= mCoeff;
60 | }
61 |
62 | /** Return true when PRBS is wrapping through initial state */
63 | bool isFinished() const { return mStartState == mState; }
64 |
65 | protected:
66 |
67 | uint64_t mCoeff; ///< polynomial coefficients. LSB is zero exponent.
68 | uint64_t mStartState; ///< initial shift register state.
69 | uint64_t mState; ///< shift register state.
70 | unsigned mLen; ///< number of bits used in shift register
71 |
72 | /** Return mask for the state register */
73 | uint64_t mask() const { return (mLen==64)?0xFFFFFFFFFFFFFFFFUL:((1<.
23 |
24 | */
25 |
26 |
27 | #include
28 | #include
29 |
30 | #include "Threads.h"
31 | #include "Timeval.h"
32 | #include "Logger.h"
33 |
34 | #ifndef gettid
35 | #include
36 | #define gettid() syscall(SYS_gettid)
37 | #endif
38 |
39 |
40 | using namespace std;
41 |
42 |
43 |
44 |
45 | Mutex gStreamLock; ///< Global lock to control access to cout and cerr.
46 |
47 | void lockCout()
48 | {
49 | gStreamLock.lock();
50 | Timeval entryTime;
51 | cout << entryTime << " " << pthread_self() << ": ";
52 | }
53 |
54 |
55 | void unlockCout()
56 | {
57 | cout << dec << endl << flush;
58 | gStreamLock.unlock();
59 | }
60 |
61 |
62 | void lockCerr()
63 | {
64 | gStreamLock.lock();
65 | Timeval entryTime;
66 | cerr << entryTime << " " << pthread_self() << ": ";
67 | }
68 |
69 | void unlockCerr()
70 | {
71 | cerr << dec << endl << flush;
72 | gStreamLock.unlock();
73 | }
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | Mutex::Mutex()
82 | {
83 | bool res;
84 | res = pthread_mutexattr_init(&mAttribs);
85 | assert(!res);
86 | res = pthread_mutexattr_settype(&mAttribs,PTHREAD_MUTEX_RECURSIVE);
87 | assert(!res);
88 | res = pthread_mutex_init(&mMutex,&mAttribs);
89 | assert(!res);
90 | }
91 |
92 |
93 | Mutex::~Mutex()
94 | {
95 | pthread_mutex_destroy(&mMutex);
96 | bool res = pthread_mutexattr_destroy(&mAttribs);
97 | assert(!res);
98 | }
99 |
100 |
101 |
102 |
103 | /** Block for the signal up to the cancellation timeout. */
104 | void Signal::wait(Mutex& wMutex, unsigned timeout) const
105 | {
106 | Timeval then(timeout);
107 | struct timespec waitTime = then.timespec();
108 | pthread_cond_timedwait(&mSignal,&wMutex.mMutex,&waitTime);
109 | }
110 |
111 | void set_selfthread_name(const char *name)
112 | {
113 | pthread_t selfid = pthread_self();
114 | pid_t tid = gettid();
115 | if (pthread_setname_np(selfid, name) == 0) {
116 | LOG(INFO) << "Thread "<< selfid << " (task " << tid << ") set name: " << name;
117 | } else {
118 | char buf[256];
119 | int err = errno;
120 | char* err_str = strerror_r(err, buf, sizeof(buf));
121 | LOG(NOTICE) << "Thread "<< selfid << " (task " << tid << ") set name \"" << name << "\" failed: (" << err << ") " << err_str;
122 | }
123 | }
124 |
125 | void Thread::start(void *(*task)(void*), void *arg)
126 | {
127 | assert(mThread==((pthread_t)0));
128 | bool res;
129 | // (pat) Moved initialization to constructor to avoid crash in destructor.
130 | //res = pthread_attr_init(&mAttrib);
131 | //assert(!res);
132 | res = pthread_attr_setstacksize(&mAttrib, mStackSize);
133 | assert(!res);
134 | res = pthread_create(&mThread, &mAttrib, task, arg);
135 | assert(!res);
136 | }
137 |
138 |
139 |
140 | // vim: ts=4 sw=4
141 |
--------------------------------------------------------------------------------
/CommonLibs/Threads.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008, 2011 Free Software Foundation, Inc.
3 | *
4 | * This software is distributed under the terms of the GNU Affero Public License.
5 | * See the COPYING file in the main directory for details.
6 | *
7 | * This use of this software may be subject to additional restrictions.
8 | * See the LEGAL file in the main directory for details.
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU Affero General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Affero General Public License for more details.
19 |
20 | You should have received a copy of the GNU Affero General Public License
21 | along with this program. If not, see .
22 |
23 | */
24 |
25 |
26 | #ifndef THREADS_H
27 | #define THREADS_H
28 |
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | class Mutex;
35 |
36 |
37 | /**@name Multithreaded access for standard streams. */
38 | //@{
39 |
40 | /**@name Functions for gStreamLock. */
41 | //@{
42 | extern Mutex gStreamLock; ///< global lock for cout and cerr
43 | void lockCerr(); ///< call prior to writing cerr
44 | void unlockCerr(); ///< call after writing cerr
45 | void lockCout(); ///< call prior to writing cout
46 | void unlockCout(); ///< call after writing cout
47 | //@}
48 |
49 | /**@name Macros for standard messages. */
50 | //@{
51 | #define COUT(text) { lockCout(); std::cout << text; unlockCout(); }
52 | #define CERR(text) { lockCerr(); std::cerr << __FILE__ << ":" << __LINE__ << ": " << text; unlockCerr(); }
53 | #ifdef NDEBUG
54 | #define DCOUT(text) {}
55 | #define OBJDCOUT(text) {}
56 | #else
57 | #define DCOUT(text) { COUT(__FILE__ << ":" << __LINE__ << " " << text); }
58 | #define OBJDCOUT(text) { DCOUT(this << " " << text); }
59 | #endif
60 | //@}
61 | //@}
62 |
63 |
64 |
65 | /**@defgroup C++ wrappers for pthread mechanisms. */
66 | //@{
67 |
68 | /** A class for recursive mutexes based on pthread_mutex. */
69 | class Mutex {
70 |
71 | private:
72 |
73 | pthread_mutex_t mMutex;
74 | pthread_mutexattr_t mAttribs;
75 |
76 | public:
77 |
78 | Mutex();
79 |
80 | ~Mutex();
81 |
82 | void lock() { pthread_mutex_lock(&mMutex); }
83 |
84 | bool trylock() { return pthread_mutex_trylock(&mMutex)==0; }
85 |
86 | void unlock() { pthread_mutex_unlock(&mMutex); }
87 |
88 | friend class Signal;
89 |
90 | };
91 |
92 |
93 | class ScopedLock {
94 |
95 | private:
96 | Mutex& mMutex;
97 |
98 | public:
99 | ScopedLock(Mutex& wMutex) :mMutex(wMutex) { mMutex.lock(); }
100 | ~ScopedLock() { mMutex.unlock(); }
101 |
102 | };
103 |
104 |
105 |
106 |
107 | /** A C++ interthread signal based on pthread condition variables. */
108 | class Signal {
109 |
110 | private:
111 |
112 | mutable pthread_cond_t mSignal;
113 |
114 | public:
115 |
116 | Signal() { int s = pthread_cond_init(&mSignal,NULL); assert(!s); }
117 |
118 | ~Signal() { pthread_cond_destroy(&mSignal); }
119 |
120 | /**
121 | Block for the signal up to the cancellation timeout.
122 | Under Linux, spurious returns are possible.
123 | */
124 | void wait(Mutex& wMutex, unsigned timeout) const;
125 |
126 | /**
127 | Block for the signal.
128 | Under Linux, spurious returns are possible.
129 | */
130 | void wait(Mutex& wMutex) const
131 | { pthread_cond_wait(&mSignal,&wMutex.mMutex); }
132 |
133 | void signal() { pthread_cond_signal(&mSignal); }
134 |
135 | void broadcast() { pthread_cond_broadcast(&mSignal); }
136 |
137 | };
138 |
139 |
140 |
141 | #define START_THREAD(thread,function,argument) \
142 | thread.start((void *(*)(void*))function, (void*)argument);
143 |
144 | void set_selfthread_name(const char *name);
145 |
146 | /** A C++ wrapper for pthread threads. */
147 | class Thread {
148 |
149 | private:
150 |
151 | pthread_t mThread;
152 | pthread_attr_t mAttrib;
153 | // FIXME -- Can this be reduced now?
154 | size_t mStackSize;
155 |
156 |
157 | public:
158 |
159 | /** Create a thread in a non-running state. */
160 | Thread(size_t wStackSize = (65536*4)):mThread((pthread_t)0) {
161 | pthread_attr_init(&mAttrib); // (pat) moved this here.
162 | mStackSize=wStackSize;
163 | }
164 |
165 | /**
166 | Destroy the Thread.
167 | It should be stopped and joined.
168 | */
169 | // (pat) If the Thread is destroyed without being started, then mAttrib is undefined. Oops.
170 | ~Thread() { pthread_attr_destroy(&mAttrib); }
171 |
172 |
173 | /** Start the thread on a task. */
174 | void start(void *(*task)(void*), void *arg);
175 |
176 | /** Join a thread that will stop on its own. */
177 | void join() {
178 | if (mThread) {
179 | int s = pthread_join(mThread, NULL);
180 | assert(!s);
181 | }
182 | }
183 |
184 | /** Send cancelation to thread */
185 | void cancel() { pthread_cancel(mThread); }
186 | };
187 |
188 |
189 |
190 |
191 | #endif
192 | // vim: ts=4 sw=4
193 |
--------------------------------------------------------------------------------
/CommonLibs/Timeval.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 |
27 |
28 | #include "Timeval.h"
29 |
30 | extern "C" {
31 | #include
32 | }
33 |
34 | using namespace std;
35 |
36 | void Timeval::now()
37 | {
38 | osmo_clock_gettime(CLOCK_REALTIME, &mTimespec);
39 | }
40 |
41 | void Timeval::future(unsigned offset)
42 | {
43 | now();
44 | unsigned sec = offset/1000;
45 | unsigned msec = offset%1000;
46 | mTimespec.tv_nsec += msec*1000*1000;
47 | mTimespec.tv_sec += sec;
48 | if (mTimespec.tv_nsec > 1000*1000*1000) {
49 | mTimespec.tv_nsec -= 1000*1000*1000;
50 | mTimespec.tv_sec += 1;
51 | }
52 | }
53 |
54 |
55 | struct timespec Timeval::timespec() const
56 | {
57 | return mTimespec;
58 | }
59 |
60 |
61 | bool Timeval::passed() const
62 | {
63 | Timeval nowTime;
64 | if (nowTime.mTimespec.tv_sec < mTimespec.tv_sec) return false;
65 | if (nowTime.mTimespec.tv_sec > mTimespec.tv_sec) return true;
66 | if (nowTime.mTimespec.tv_nsec >= mTimespec.tv_nsec) return true;
67 | return false;
68 | }
69 |
70 | double Timeval::seconds() const
71 | {
72 | return ((double)mTimespec.tv_sec) + 1e-9*((double)mTimespec.tv_nsec);
73 | }
74 |
75 |
76 |
77 | long Timeval::delta(const Timeval& other) const
78 | {
79 | // 2^31 milliseconds is just over 4 years.
80 | int32_t deltaS = other.sec() - sec();
81 | int32_t deltaNs = other.nsec() - nsec();
82 | return 1000*deltaS + deltaNs/1000000;
83 | }
84 |
85 |
86 |
87 |
88 | ostream& operator<<(ostream& os, const Timeval& tv)
89 | {
90 | os.setf( ios::fixed, ios::floatfield );
91 | os << tv.seconds();
92 | return os;
93 | }
94 |
95 |
96 | ostream& operator<<(ostream& os, const struct timespec& ts)
97 | {
98 | os << ts.tv_sec << "," << ts.tv_nsec/1000;
99 | return os;
100 | }
101 |
102 |
103 |
104 | // vim: ts=4 sw=4
105 |
--------------------------------------------------------------------------------
/CommonLibs/Timeval.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | * This software is distributed under the terms of the GNU Affero Public License.
5 | * See the COPYING file in the main directory for details.
6 | *
7 | * This use of this software may be subject to additional restrictions.
8 | * See the LEGAL file in the main directory for details.
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU Affero General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Affero General Public License for more details.
19 |
20 | You should have received a copy of the GNU Affero General Public License
21 | along with this program. If not, see .
22 |
23 | */
24 |
25 |
26 | #ifndef TIMEVAL_H
27 | #define TIMEVAL_H
28 |
29 | #include
30 | #include "sys/time.h"
31 | #include
32 | #include
33 |
34 |
35 |
36 | /** A wrapper on usleep to sleep for milliseconds. */
37 | inline void msleep(long v) { usleep(v*1000); }
38 |
39 |
40 | /** A C++ wrapper for struct timeval. */
41 | class Timeval {
42 |
43 | private:
44 |
45 | struct timespec mTimespec;
46 |
47 | public:
48 |
49 | /** Set the value to current time. */
50 | void now();
51 |
52 | /** Set the value to gettimeofday plus an offset. */
53 | void future(unsigned ms);
54 |
55 | //@{
56 | Timeval(unsigned sec, unsigned usec)
57 | {
58 | mTimespec.tv_sec = sec;
59 | mTimespec.tv_nsec = usec*1000;
60 | }
61 |
62 | Timeval(const struct timeval& wTimeval)
63 | {
64 | mTimespec.tv_sec = wTimeval.tv_sec;
65 | mTimespec.tv_nsec = wTimeval.tv_sec*1000;
66 | }
67 |
68 | /**
69 | Create a Timespec offset into the future.
70 | @param offset milliseconds
71 | */
72 | Timeval(unsigned offset=0) { future(offset); }
73 | //@}
74 |
75 | /** Convert to a struct timespec. */
76 | struct timespec timespec() const;
77 |
78 | /** Return total seconds. */
79 | double seconds() const;
80 |
81 | uint32_t sec() const { return mTimespec.tv_sec; }
82 | uint32_t usec() const { return mTimespec.tv_nsec / 1000; }
83 | uint32_t nsec() const { return mTimespec.tv_nsec; }
84 |
85 | /** Return differnce from other (other-self), in ms. */
86 | long delta(const Timeval& other) const;
87 |
88 | /** Elapsed time in ms. */
89 | long elapsed() const { return delta(Timeval()); }
90 |
91 | /** Remaining time in ms. */
92 | long remaining() const { return -elapsed(); }
93 |
94 | /** Return true if the time has passed, as per clock_gettime(CLOCK_REALTIME). */
95 | bool passed() const;
96 |
97 | /** Add a given number of minutes to the time. */
98 | void addMinutes(unsigned minutes) { mTimespec.tv_sec += minutes*60; }
99 |
100 | };
101 |
102 | std::ostream& operator<<(std::ostream& os, const Timeval&);
103 |
104 | std::ostream& operator<<(std::ostream& os, const struct timespec&);
105 |
106 |
107 | #endif
108 | // vim: ts=4 sw=4
109 |
--------------------------------------------------------------------------------
/CommonLibs/Utils.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 sysmocom - s.f.m.c. GmbH
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public
15 | * License along with this library; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | std::vector comma_delimited_to_vector(const char* opt)
24 | {
25 | std::string str = std::string(opt);
26 | std::vector result;
27 | std::stringstream ss(str);
28 |
29 | while( ss.good() )
30 | {
31 | std::string substr;
32 | getline(ss, substr, ',');
33 | result.push_back(substr);
34 | }
35 | return result;
36 | }
37 |
--------------------------------------------------------------------------------
/CommonLibs/Utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 sysmocom - s.f.m.c. GmbH
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public
15 | * License along with this library; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | #pragma once
20 |
21 | #include
22 | #include
23 |
24 | std::vector comma_delimited_to_vector(const char* opt);
25 |
--------------------------------------------------------------------------------
/CommonLibs/config_defs.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 | * This file contains structures used by both VTY (C, dir CommonLibs) and
5 | * osmo-trx (CXX, dir Transceiver52)
6 | */
7 |
8 | enum FillerType {
9 | FILLER_DUMMY,
10 | FILLER_ZERO,
11 | FILLER_NORM_RAND,
12 | FILLER_EDGE_RAND,
13 | FILLER_ACCESS_RAND,
14 | };
15 |
16 | enum ReferenceType {
17 | REF_INTERNAL,
18 | REF_EXTERNAL,
19 | REF_GPS,
20 | };
21 |
--------------------------------------------------------------------------------
/CommonLibs/debug.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "debug.h"
4 |
5 | /* default categories */
6 | static const struct log_info_cat default_categories[] = {
7 | [DMAIN] = {
8 | .name = "DMAIN",
9 | .description = "Main generic category",
10 | .color = NULL,
11 | .enabled = 1, .loglevel = LOGL_NOTICE,
12 | },
13 | [DTRXCTRL] = {
14 | .name = "DTRXCTRL",
15 | .description = "TRX CTRL interface",
16 | .color = "\033[1;33m",
17 | .enabled = 1, .loglevel = LOGL_NOTICE,
18 | },
19 | [DDEV] = {
20 | .name = "DDEV",
21 | .description = "Device/Driver specific code",
22 | .color = NULL,
23 | .enabled = 1, .loglevel = LOGL_INFO,
24 | },
25 | [DLMS] = {
26 | .name = "DLMS",
27 | .description = "Logging from within LimeSuite itself",
28 | .color = NULL,
29 | .enabled = 1, .loglevel = LOGL_NOTICE,
30 | },
31 | };
32 |
33 | const struct log_info log_info = {
34 | .cat = default_categories,
35 | .num_cat = ARRAY_SIZE(default_categories),
36 | };
37 |
--------------------------------------------------------------------------------
/CommonLibs/debug.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | extern const struct log_info log_info;
4 |
5 | /* Debug Areas of the code */
6 | enum {
7 | DMAIN,
8 | DTRXCTRL,
9 | DDEV,
10 | DLMS,
11 | };
12 |
--------------------------------------------------------------------------------
/CommonLibs/osmo_signal.h:
--------------------------------------------------------------------------------
1 | /* Generic signalling/notification infrastructure */
2 | /* (C) 2018 by sysmocom s.f.m.c. GmbH
3 | *
4 | * Author: Pau Espin Pedrol
5 | *
6 | * All Rights Reserved
7 | *
8 | * This program is free software; you can redistribute it and/or modify
9 | * it under the terms of the GNU Affero General Public License as published by
10 | * the Free Software Foundation; either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Affero General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Affero General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 |
23 | #pragma once
24 |
25 | #include
26 |
27 | /* Signalling subsystems */
28 | enum signal_subsystems {
29 | SS_TRANSC,
30 | };
31 |
32 | /* SS_TRANSC signals */
33 | enum SS_TRANSC {
34 | S_TRANSC_STOP_REQUIRED, /* Transceiver fatal error, it should be stopped */
35 | };
36 |
--------------------------------------------------------------------------------
/CommonLibs/trx_vty.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "config_defs.h"
6 |
7 | extern struct vty_app_info g_vty_info;
8 |
9 | #define TRX_CHAN_MAX 8
10 |
11 | /* Samples-per-symbol for downlink path
12 | * 4 - Uses precision modulator (more computation, less distortion)
13 | * 1 - Uses minimized modulator (less computation, more distortion)
14 | *
15 | * Other values are invalid. Receive path (uplink) is always
16 | * downsampled to 1 sps. Default to 4 sps for all cases.
17 | */
18 | #define DEFAULT_TX_SPS 4
19 |
20 | /*
21 | * Samples-per-symbol for uplink (receiver) path
22 | * Do not modify this value. EDGE configures 4 sps automatically on
23 | * B200/B210 devices only. Use of 4 sps on the receive path for other
24 | * configurations is not supported.
25 | */
26 | #define DEFAULT_RX_SPS 1
27 |
28 | /* Default configuration parameters */
29 | #define DEFAULT_TRX_PORT 5700
30 | #define DEFAULT_TRX_IP "127.0.0.1"
31 | #define DEFAULT_CHANS 1
32 |
33 | struct trx_ctx;
34 |
35 | struct trx_chan {
36 | struct trx_ctx *trx; /* backpointer */
37 | unsigned int idx; /* channel index */
38 | char *rx_path;
39 | char *tx_path;
40 | };
41 |
42 | struct trx_ctx {
43 | struct {
44 | char *bind_addr;
45 | char *remote_addr;
46 | char *dev_args;
47 | unsigned int base_port;
48 | unsigned int tx_sps;
49 | unsigned int rx_sps;
50 | unsigned int rtsc;
51 | bool rtsc_set;
52 | unsigned int rach_delay;
53 | bool rach_delay_set;
54 | enum ReferenceType clock_ref;
55 | enum FillerType filler;
56 | bool multi_arfcn;
57 | double offset;
58 | double rssi_offset;
59 | bool swap_channels;
60 | bool ext_rach;
61 | bool egprs;
62 | unsigned int sched_rr;
63 | unsigned int num_chans;
64 | struct trx_chan chans[TRX_CHAN_MAX];
65 | } cfg;
66 | };
67 |
68 | int trx_vty_init(struct trx_ctx* trx);
69 | struct trx_ctx *vty_trx_ctx_alloc(void *talloc_ctx);
70 |
--------------------------------------------------------------------------------
/GSM/GSMCommon.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | * Copyright 2011 Range Networks, Inc.
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 |
27 | #include "GSMCommon.h"
28 |
29 | using namespace GSM;
30 | using namespace std;
31 |
32 |
33 | const BitVector GSM::gTrainingSequence[] = {
34 | BitVector("00100101110000100010010111"),
35 | BitVector("00101101110111100010110111"),
36 | BitVector("01000011101110100100001110"),
37 | BitVector("01000111101101000100011110"),
38 | BitVector("00011010111001000001101011"),
39 | BitVector("01001110101100000100111010"),
40 | BitVector("10100111110110001010011111"),
41 | BitVector("11101111000100101110111100"),
42 | };
43 |
44 | const BitVector GSM::gEdgeTrainingSequence[] = {
45 | BitVector("111111001111111001111001001001111111111111001111111111001111111001111001001001"),
46 | BitVector("111111001111001001111001001001111001001001001111111111001111001001111001001001"),
47 | BitVector("111001111111111111001001001111001001001111001111111001111111111111001001001111"),
48 | BitVector("111001111111111001001001001111001001111001111111111001111111111001001001001111"),
49 | BitVector("111111111001001111001111001001001111111001111111111111111001001111001111001001"),
50 | BitVector("111001111111001001001111001111001001111111111111111001111111001001001111001111"),
51 | BitVector("001111001111111001001001001001111001001111111111001111001111111001001001001001"),
52 | BitVector("001001001111001001001001111111111001111111001111001001001111001001001001111111"),
53 | };
54 |
55 | const BitVector GSM::gDummyBurst("0001111101101110110000010100100111000001001000100000001111100011100010111000101110001010111010010100011001100111001111010011111000100101111101010000");
56 |
57 | /* 3GPP TS 05.02, section 5.2.7 "Access burst (AB)", synch. sequence bits */
58 | const BitVector GSM::gRACHSynchSequenceTS0("01001011011111111001100110101010001111000"); /* GSM, GMSK (default) */
59 | const BitVector GSM::gRACHSynchSequenceTS1("01010100111110001000011000101111001001101"); /* EGPRS, 8-PSK */
60 | const BitVector GSM::gRACHSynchSequenceTS2("11101111001001110101011000001101101110111"); /* EGPRS, GMSK */
61 |
62 | // |-head-||---------midamble----------------------||--------------data----------------||t|
63 | const BitVector GSM::gRACHBurst("0011101001001011011111111001100110101010001111000110111101111110000111001001010110011000");
64 |
65 |
66 | int32_t GSM::FNDelta(int32_t v1, int32_t v2)
67 | {
68 | static const int32_t halfModulus = gHyperframe/2;
69 | int32_t delta = v1-v2;
70 | if (delta>=halfModulus) delta -= gHyperframe;
71 | else if (delta<-halfModulus) delta += gHyperframe;
72 | return (int32_t) delta;
73 | }
74 |
75 | int GSM::FNCompare(int32_t v1, int32_t v2)
76 | {
77 | int32_t delta = FNDelta(v1,v2);
78 | if (delta>0) return 1;
79 | if (delta<0) return -1;
80 | return 0;
81 | }
82 |
83 |
84 |
85 |
86 | ostream& GSM::operator<<(ostream& os, const Time& t)
87 | {
88 | os << t.TN() << ":" << t.FN();
89 | return os;
90 | }
91 |
92 |
93 | // vim: ts=4 sw=4
94 |
--------------------------------------------------------------------------------
/GSM/Makefile.am:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008 Free Software Foundation, Inc.
3 | #
4 | # This software is distributed under the terms of the GNU Public License.
5 | # See the COPYING file in the main directory for details.
6 | #
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see .
19 | #
20 |
21 | include $(top_srcdir)/Makefile.common
22 |
23 | AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES)
24 | #AM_CXXFLAGS = -O2 -g
25 |
26 | noinst_LTLIBRARIES = libGSM.la
27 |
28 | libGSM_la_SOURCES = \
29 | GSMCommon.cpp
30 |
31 | noinst_HEADERS = \
32 | GSMCommon.h
33 |
--------------------------------------------------------------------------------
/INSTALLATION:
--------------------------------------------------------------------------------
1 | Installation Requirements
2 |
3 |
4 |
5 | osmo-trx compiles to a simple Unix binary and does not require special
6 | installation.
7 |
8 | One some systems (Ubuntu), you will need to define LIBS = -lpthread prior to
9 | running configure.
10 |
11 | To run osmo-trx, the following should be installed:
12 | libuhd (https://gnuradio.org).
13 | This is part of the GNURadio installation.
14 |
15 | For information on specific executables, see tests/README.tests and
16 | apps/README.apps.
17 |
18 | See https://osmocom.org/projects/osmotrx/wiki/OsmoTRX for more
19 | information.
20 |
--------------------------------------------------------------------------------
/LEGAL:
--------------------------------------------------------------------------------
1 | OpenBTS
2 |
3 | The OsmoTRX project is direved from OpenBTS transceiver code. See http://openbts.org/ for details.
4 |
5 | The related copyrights:
6 | Most parts copyright 2008-2011 Free Software Foundation.
7 | Some parts copyright 2010 Kestrel Signal Processing, Inc.
8 | Some parts copyright 2011 Range Networks, Inc.
9 |
10 |
11 | Patent Laws
12 |
13 | The use of this software to provide GSM services may result in the use of
14 | patented technologies. The user of this software is required to take whatever
15 | actions are necessary to avoid patent infringement.
16 |
17 |
18 | Telecom and Radio Spectrum Laws
19 |
20 | The primary function of OsmoTRX is the provision of telecommunications service
21 | over a radio link. This activity is heavily regulated nearly everywhere in
22 | the world. Users of this software are expected to comply with local and national
23 | regulations in the jurisdictions where this sortware is used with radio equipment.
24 |
25 |
26 | Legal Summary
27 |
28 | The user of this software is expected to comply with all applicable laws and
29 | regulations, including patent laws, copyright laws, and telecommunications
30 | regulations.
31 |
32 | The legal restrictions listed here are not necessarily exhaustive.
33 |
34 |
35 | Note to US Government Users
36 |
37 | The OsmoTRX software applications and associated documentation are "Commercial
38 | Item(s)," as that term is defined at 48 C.F.R. Section 2.101, consisting of
39 | "Commercial Computer Software" and "Commercial Computer Software Documentation,"
40 | as such terms are used in 48 C.F.R. 12.212 or 48 C.F.R. 227.7202, as
41 | applicable. Consistent with 48 C.F.R. 12.212 or 48 C.F.R. Sections 227.7202-1
42 | through 227.7202-4, as applicable, the Commercial Computer Software and
43 | Commercial Computer Software Documentation are being licensed to U.S. Government
44 | end users (a) only as Commercial Items and (b) with only those rights as are
45 | granted to all other end users pursuant to the terms and conditions of GPLv3
46 | and AGPLv3.
47 |
48 |
49 | Note to US Government Contractors
50 |
51 | GPL is not compatible with "government purpose rights" (GPR). If you receive
52 | OsmoTRX software under a GPL and deliver it under GPR, you will be in violation
53 | of GPL and possibly subject to enforcement actions by the original authors and
54 | copyright holders, including the Free Software Foundation, Inc.
55 |
56 |
57 | Software Licensing and Distribution
58 |
59 | The OsmoTRX is distributed publicly under AGPLv3. See the COPYING file
60 | for more information on the license for this distribution.
61 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008 Free Software Foundation, Inc.
3 | #
4 | # This software is distributed under the terms of the GNU Public License.
5 | # See the COPYING file in the main directory for details.
6 | #
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see .
19 | #
20 |
21 | include $(top_srcdir)/Makefile.common
22 |
23 | ACLOCAL_AMFLAGS = -I config
24 | AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(USB_INCLUDES) $(WITH_INCLUDES)
25 | AM_CXXFLAGS = -Wall -pthread
26 | #AM_CXXFLAGS = -Wall -O2 -NDEBUG -pthread
27 | #AM_CFLAGS = -Wall -O2 -NDEBUG -pthread
28 |
29 | # Order must be preserved
30 | SUBDIRS = \
31 | doc \
32 | CommonLibs \
33 | GSM \
34 | Transceiver52M \
35 | contrib \
36 | tests
37 |
38 | EXTRA_DIST = \
39 | autogen.sh \
40 | INSTALLATION \
41 | LEGAL \
42 | COPYING \
43 | README
44 |
45 | AM_DISTCHECK_CONFIGURE_FLAGS = \
46 | --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
47 |
48 | .PHONY: release
49 |
50 | @RELMAKE@
51 |
52 | dox: FORCE
53 | doxygen doxconfig
54 |
55 | FORCE:
56 |
--------------------------------------------------------------------------------
/Makefile.common:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008 Free Software Foundation, Inc.
3 | #
4 | # This software is distributed under the terms of the GNU Public License.
5 | # See the COPING file in the main directory for details.
6 | #
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see .
19 | #
20 |
21 | COMMON_INCLUDEDIR = $(top_srcdir)/CommonLibs
22 | GSM_INCLUDEDIR = $(top_srcdir)/GSM
23 |
24 | STD_DEFINES_AND_INCLUDES = \
25 | $(SVNDEV) \
26 | -I$(COMMON_INCLUDEDIR) \
27 | -I$(GSM_INCLUDEDIR)
28 |
29 | COMMON_LA = $(top_builddir)/CommonLibs/libcommon.la
30 | GSM_LA = $(top_builddir)/GSM/libGSM.la
31 |
32 | if ARCH_ARM
33 | ARCH_LA = $(top_builddir)/Transceiver52M/arch/arm/libarch.la
34 | else
35 | ARCH_LA = $(top_builddir)/Transceiver52M/arch/x86/libarch.la
36 | endif
37 |
38 | MOSTLYCLEANFILES = *~
39 |
--------------------------------------------------------------------------------
/NEWS:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttsou/osmo-trx/5e6f3e0cadf7859ae90073cd07afec550892a448/NEWS
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This is the interface to the transcevier.
2 |
3 | Each TRX Manager UDP socket interface represents a single ARFCN.
4 | Each of these per-ARFCN interfaces is a pair of UDP sockets, one for control and one for data.
5 | Give a base port B (5700), the master clock interface is at port P=B.
6 | The TRX-side control interface for C(N) is on port P=B+2N+1 and the data interface is on an odd numbered port P=B+2N+2.
7 | The corresponding core-side interface for every socket is at P+100.
8 | For any given build, the number of ARFCN interfaces can be fixed.
9 |
10 |
11 |
12 | Indications on the Master Clock Interface
13 |
14 | The master clock interface is output only (from the radio).
15 | Messages are "indications".
16 |
17 | CLOCK gives the current value of the transceiver clock to be used by the core.
18 | This message is sent whenever a trasmission packet arrives that is too late or too early. The clock value is NOT the current transceiver time. It is a time setting the the core should use to give better packet arrival times.
19 | IND CLOCK
20 |
21 |
22 |
23 | Commands on the Per-ARFCN Control Interface
24 |
25 | The per-ARFCN control interface uses a command-reponse protocol.
26 | Commands are NULL-terminated ASCII strings, one per UDP socket.
27 | Each command has a corresponding response.
28 | Every command is of the form:
29 |
30 | CMD [params]
31 |
32 | The is the actual command.
33 | Parameters are optional depending on the commands type.
34 | Every response is of the form:
35 |
36 | RSP [result]
37 |
38 | The is 0 for success and a non-zero error code for failure.
39 | Successful responses may include results, depending on the command type.
40 |
41 |
42 | Power Control
43 |
44 | POWEROFF shuts off transmitter power and stops the demodulator.
45 | CMD POWEROFF
46 | RSP POWEROFF
47 |
48 | POWERON starts the transmitter and starts the demodulator. Initial power level is very low.
49 | This command fails if the transmitter and receiver are not yet tuned.
50 | This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
51 | If the transceiver is already on, it response with success to this command.
52 | CMD POWERON
53 | RSP POWERON
54 |
55 | SETPOWER sets output power in dB wrt full scale.
56 | This command fails if the transmitter and receiver are not running.
57 | CMD SETPOWER
58 | RSP SETPOWER
59 |
60 | ADJPOWER adjusts power by the given dB step. Response returns resulting power level wrt full scale.
61 | This command fails if the transmitter and receiver are not running.
62 | CMD ADJPOWER
63 | RSP ADJPOWER
64 |
65 |
66 | Tuning Control
67 |
68 | RXTUNE tunes the receiver to a given frequency in kHz.
69 | This command fails if the receiver is already running.
70 | (To re-tune you stop the radio, re-tune, and restart.)
71 | This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
72 | CMD RXTUNE
73 | RSP RXTUNE
74 |
75 | TXTUNE tunes the transmitter to a given frequency in kHz.
76 | This command fails if the transmitter is already running.
77 | (To re-tune you stop the radio, re-tune, and restart.)
78 | This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
79 | CMD TXTUNE
80 | RSP TXTUNE
81 |
82 |
83 | Timeslot Control
84 |
85 | SETSLOT sets the format of the uplink timeslots in the ARFCN.
86 | The indicates the timeslot of interest.
87 | The indicates the type of channel that occupies the timeslot.
88 | A chantype of zero indicates the timeslot is off.
89 | CMD SETSLOT
90 | RSP SETSLOT
91 |
92 |
93 | Messages on the per-ARFCN Data Interface
94 |
95 | Messages on the data interface carry one radio burst per UDP message.
96 |
97 |
98 | Received Data Burst
99 |
100 | 1 byte timeslot index
101 | 4 bytes GSM frame number, big endian
102 | 1 byte RSSI in -dBm
103 | 2 bytes correlator timing offset in 1/256 symbol steps, 2's-comp, big endian
104 | 148 bytes soft symbol estimates, 0 -> definite "0", 255 -> definite "1"
105 |
106 |
107 | Transmit Data Burst
108 |
109 | 1 byte timeslot index
110 | 4 bytes GSM frame number, big endian
111 | 1 byte transmit level wrt ARFCN max, -dB (attenuation)
112 | 148 bytes output symbol values, 0 & 1
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/Transceiver52M/Channelizer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Polyphase channelizer
3 | *
4 | * Copyright (C) 2012-2014 Tom Tsou
5 | * Copyright (C) 2015 Ettus Research LLC
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Affero General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Affero General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Affero General Public License
18 | * along with this program. If not, see .
19 | * See the COPYING file in the main directory for details.
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "Channelizer.h"
29 |
30 | extern "C" {
31 | #include "fft.h"
32 | #include "convolve.h"
33 | }
34 |
35 | static void deinterleave(const float *in, size_t ilen,
36 | float **out, size_t olen, size_t m)
37 | {
38 | size_t i, n;
39 |
40 | for (i = 0; i < olen; i++) {
41 | for (n = 0; n < m; n++) {
42 | out[m - 1 - n][2 * i + 0] = in[2 * (i * m + n) + 0];
43 | out[m - 1 - n][2 * i + 1] = in[2 * (i * m + n) + 1];
44 | }
45 | }
46 | }
47 |
48 | size_t Channelizer::inputLen() const
49 | {
50 | return blockLen * m;
51 | }
52 |
53 | size_t Channelizer::outputLen() const
54 | {
55 | return blockLen;
56 | }
57 |
58 | float *Channelizer::outputBuffer(size_t chan) const
59 | {
60 | if (chan >= m)
61 | return NULL;
62 |
63 | return hInputs[chan];
64 | }
65 |
66 | /*
67 | * Implementation based on material found in:
68 | *
69 | * "harris, fred, Multirate Signal Processing, Upper Saddle River, NJ,
70 | * Prentice Hall, 2006."
71 | */
72 | bool Channelizer::rotate(const float *in, size_t len)
73 | {
74 | size_t hSize = 2 * hLen * sizeof(float);
75 |
76 | if (!checkLen(blockLen, len))
77 | return false;
78 |
79 | deinterleave(in, len, hInputs, blockLen, m);
80 |
81 | /*
82 | * Convolve through filterbank while applying and saving sample history
83 | */
84 | for (size_t i = 0; i < m; i++) {
85 | memcpy(&hInputs[i][2 * -hLen], hist[i], hSize);
86 | memcpy(hist[i], &hInputs[i][2 * (blockLen - hLen)], hSize);
87 |
88 | convolve_real(hInputs[i], blockLen,
89 | subFilters[i], hLen,
90 | hOutputs[i], blockLen,
91 | 0, blockLen);
92 | }
93 |
94 | cxvec_fft(fftHandle);
95 |
96 | return true;
97 | }
98 |
99 | /* Setup channelizer paramaters */
100 | Channelizer::Channelizer(size_t m, size_t blockLen, size_t hLen)
101 | : ChannelizerBase(m, blockLen, hLen)
102 | {
103 | }
104 |
105 | Channelizer::~Channelizer()
106 | {
107 | }
108 |
--------------------------------------------------------------------------------
/Transceiver52M/Channelizer.h:
--------------------------------------------------------------------------------
1 | #ifndef _CHANNELIZER_RX_H_
2 | #define _CHANNELIZER_RX_H_
3 |
4 | #include "ChannelizerBase.h"
5 |
6 | class Channelizer : public ChannelizerBase {
7 | public:
8 | /** Constructor for channelizing filter bank
9 | @param m number of physical channels
10 | @param blockLen number of samples per output of each iteration
11 | @param hLen number of taps in each constituent filter path
12 | */
13 | Channelizer(size_t m, size_t blockLen, size_t hLen = 16);
14 | ~Channelizer();
15 |
16 | /* Return required input and output buffer lengths */
17 | size_t inputLen() const;
18 | size_t outputLen() const;
19 |
20 | /** Rotate "input commutator" and drive samples through filterbank
21 | @param in complex input vector
22 | @param iLen number of samples in buffer (must match block length)
23 | @return false on error and true otherwise
24 | */
25 | bool rotate(const float *in, size_t iLen);
26 |
27 | /** Get buffer for an output path
28 | @param chan channel number of filterbank
29 | @return NULL on error and pointer to buffer otherwise
30 | */
31 | float *outputBuffer(size_t chan) const;
32 | };
33 |
34 | #endif /* _CHANNELIZER_RX_H_ */
35 |
--------------------------------------------------------------------------------
/Transceiver52M/ChannelizerBase.h:
--------------------------------------------------------------------------------
1 | #ifndef _CHANNELIZER_BASE_H_
2 | #define _CHANNELIZER_BASE_H_
3 |
4 | class ChannelizerBase {
5 | protected:
6 | ChannelizerBase(size_t m, size_t blockLen, size_t hLen);
7 | ~ChannelizerBase();
8 |
9 | /* Channelizer parameters */
10 | size_t m;
11 | size_t hLen;
12 | size_t blockLen;
13 |
14 | /* Channelizer filterbank sub-filters */
15 | float **subFilters;
16 |
17 | /* Input/Output buffers */
18 | float **hInputs, **hOutputs, **hist;
19 | float *fftInput, *fftOutput;
20 |
21 | /* Pointer to opaque FFT instance */
22 | struct fft_hdl *fftHandle;
23 |
24 | /* Initializer internals */
25 | bool initFilters();
26 | bool initFFT();
27 | void releaseFilters();
28 |
29 | /* Map overlapped FFT and filter I/O buffers */
30 | bool mapBuffers();
31 |
32 | /* Buffer length validity checking */
33 | bool checkLen(size_t innerLen, size_t outerLen);
34 | public:
35 | /* Initilize channelizer/synthesis filter internals */
36 | bool init();
37 | };
38 |
39 | #endif /* _CHANNELIZER_BASE_H_ */
40 |
--------------------------------------------------------------------------------
/Transceiver52M/Makefile.am:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2008 Free Software Foundation, Inc.
3 | # Copyright 2010 Range Networks, Inc.
4 | #
5 | # This software is distributed under the terms of the GNU Public License.
6 | # See the COPYING file in the main directory for details.
7 | #
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 | #
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 | #
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 | #
21 |
22 | include $(top_srcdir)/Makefile.common
23 |
24 | SUBDIRS = arch device
25 |
26 | AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/arch/common -I${srcdir}/device
27 | AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS)
28 |
29 | rev2dir = $(datadir)/usrp/rev2
30 | rev4dir = $(datadir)/usrp/rev4
31 |
32 | dist_rev2_DATA = std_inband.rbf
33 | dist_rev4_DATA = std_inband.rbf
34 |
35 | EXTRA_DIST = README
36 |
37 | noinst_LTLIBRARIES = libtransceiver_common.la
38 |
39 | COMMON_SOURCES = \
40 | radioInterface.cpp \
41 | radioVector.cpp \
42 | radioClock.cpp \
43 | radioBuffer.cpp \
44 | sigProcLib.cpp \
45 | signalVector.cpp \
46 | Transceiver.cpp \
47 | ChannelizerBase.cpp \
48 | Channelizer.cpp \
49 | Synthesis.cpp
50 |
51 | libtransceiver_common_la_SOURCES = \
52 | $(COMMON_SOURCES) \
53 | Resampler.cpp \
54 | radioInterfaceResamp.cpp \
55 | radioInterfaceMulti.cpp
56 |
57 | noinst_HEADERS = \
58 | Complex.h \
59 | radioInterface.h \
60 | radioVector.h \
61 | radioClock.h \
62 | radioBuffer.h \
63 | sigProcLib.h \
64 | signalVector.h \
65 | Transceiver.h \
66 | Resampler.h \
67 | ChannelizerBase.h \
68 | Channelizer.h \
69 | Synthesis.h
70 |
71 | COMMON_LDADD = \
72 | libtransceiver_common.la \
73 | $(ARCH_LA) \
74 | $(GSM_LA) \
75 | $(COMMON_LA) \
76 | $(FFTWF_LIBS) \
77 | $(LIBOSMOCORE_LIBS) \
78 | $(LIBOSMOCTRL_LIBS) \
79 | $(LIBOSMOVTY_LIBS)
80 |
81 | bin_PROGRAMS =
82 |
83 | if DEVICE_UHD
84 | bin_PROGRAMS += osmo-trx-uhd
85 | osmo_trx_uhd_SOURCES = osmo-trx.cpp
86 | osmo_trx_uhd_LDADD = \
87 | $(builddir)/device/uhd/libdevice.la \
88 | $(COMMON_LDADD) \
89 | $(UHD_LIBS)
90 | osmo_trx_uhd_CPPFLAGS = $(AM_CPPFLAGS) $(UHD_CFLAGS)
91 | endif
92 |
93 | if DEVICE_USRP1
94 | bin_PROGRAMS += osmo-trx-usrp1
95 | osmo_trx_usrp1_SOURCES = osmo-trx.cpp
96 | osmo_trx_usrp1_LDADD = \
97 | $(builddir)/device/usrp1/libdevice.la \
98 | $(COMMON_LDADD) \
99 | $(USRP_LIBS)
100 | osmo_trx_usrp1_CPPFLAGS = $(AM_CPPFLAGS) $(USRP_CFLAGS)
101 | endif
102 |
103 | if DEVICE_LMS
104 | bin_PROGRAMS += osmo-trx-lms
105 | osmo_trx_lms_SOURCES = osmo-trx.cpp
106 | osmo_trx_lms_LDADD = \
107 | $(builddir)/device/lms/libdevice.la \
108 | $(COMMON_LDADD) \
109 | $(LMS_LIBS)
110 | osmo_trx_lms_CPPFLAGS = $(AM_CPPFLAGS) $(LMS_CFLAGS)
111 | endif
112 |
--------------------------------------------------------------------------------
/Transceiver52M/README:
--------------------------------------------------------------------------------
1 | The Transceiver
2 |
3 | The transceiver consists of three modules:
4 | --- transceiver
5 | --- radioInterface
6 | --- USRPDevice
7 |
8 | The USRPDevice module is basically a driver that reads/writes
9 | packets to a USRP with two RFX900 daughterboards, board
10 | A is the Tx chain and board B is the Rx chain.
11 |
12 | The radioInterface module is basically an interface b/w the
13 | transceiver and the USRP. It operates the basestation clock
14 | based upon the sample count of received USRP samples. Packets
15 | from the USRP are queued and segmented into GSM bursts that are
16 | passed up to the transceiver; bursts from the transceiver are
17 | passed down to the USRP.
18 |
19 | The transceiver basically operates "layer 0" of the GSM stack,
20 | performing the modulation, detection, and demodulation of GSM
21 | bursts. It communicates with the GSM stack via three UDP sockets,
22 | one socket for data, one for control messages, and one socket to
23 | pass clocking information. The transceiver contains a priority
24 | queue to sort to-be-transmitted bursts, and a filler table to fill
25 | in timeslots that do not have bursts in the priority queue. The
26 | transceiver tries to stay ahead of the basestation clock, adapting
27 | its latency when underruns are reported by the radioInterface/USRP.
28 | Received bursts (from the radioInterface) pass through a simple
29 | energy detector, a RACH or midamble correlator, and a DFE-based demodulator.
30 |
31 | NOTE: There's a SWLOOPBACK #define statement, where the USRP is replaced
32 | with a memory buffer. In this mode, data written to the USRP is actually stored
33 | in a buffer, and read commands to the USRP simply pull data from this buffer.
34 | This was very useful in early testing, and still may be useful in testing basic
35 | Transceiver and radioInterface functionality.
36 |
--------------------------------------------------------------------------------
/Transceiver52M/README.DFEsymbolspaced:
--------------------------------------------------------------------------------
1 | signalVectors G0, G1. i.e. G0(D) = 1 +2D + 3D^2 = [1 2 3]
2 | G0(D) = 1/sqrt(SNR).
3 | G1(D) = [h0 h1D .. h_(N-1)D^(N-1)]
4 | for i = 0,1,...,N_f-1,
5 | d = |G0(0)|^2+|G1(0)|^2
6 | l_i(D) = D^i ( G0(D)*G0'(0) + G1(D)*G1'(0) )/d
7 | k = G1(0)/G0(0)
8 | G0n(D) = G0(D)+k'*G1(D)
9 | G1n(D) = (-G0(D)*k+G1(D))/D
10 | G0(D) = G0n(D)/sqrt(1+k*k')
11 | G1(D) = G1n(D)/sqrt(1+k*k')
12 | end
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Transceiver52M/Resampler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Rational Sample Rate Conversion
3 | * Copyright (C) 2012, 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #ifndef _RESAMPLER_H_
21 | #define _RESAMPLER_H_
22 |
23 | #include
24 | #include
25 |
26 | class Resampler {
27 | public:
28 | /* Constructor for rational sample rate conversion
29 | * @param p numerator of resampling ratio
30 | * @param q denominator of resampling ratio
31 | * @param filt_len length of each polyphase subfilter
32 | */
33 | Resampler(size_t p, size_t q, size_t filt_len = 16);
34 | ~Resampler();
35 |
36 | /* Initilize resampler filterbank.
37 | * @param bw bandwidth factor on filter generation (pre-window)
38 | * @return false on error, zero otherwise
39 | *
40 | * Automatic setting is to compute the filter to prevent aliasing with
41 | * a Blackman-Harris window. Adjustment is made through a bandwith
42 | * factor to shift the cutoff and/or the constituent filter lengths.
43 | * Calculation of specific rolloff factors or 3-dB cutoff points is
44 | * left as an excersize for the reader.
45 | */
46 | bool init(float bw = 1.0f);
47 |
48 | /* Rotate "commutator" and drive samples through filterbank
49 | * @param in continuous buffer of input complex float values
50 | * @param in_len input buffer length
51 | * @param out continuous buffer of output complex float values
52 | * @param out_len output buffer length
53 | * @return number of samples outputted, negative on error
54 | *
55 | * Input and output vector lengths must of be equal multiples of the
56 | * rational conversion rate denominator and numerator respectively.
57 | */
58 | int rotate(const float *in, size_t in_len, float *out, size_t out_len);
59 |
60 | /* Get filter length
61 | * @return number of taps in each filter partition
62 | */
63 | size_t len();
64 |
65 | private:
66 | size_t p;
67 | size_t q;
68 | size_t filt_len;
69 | std::vector in_index;
70 | std::vector out_path;
71 | std::vector *> partitions;
72 |
73 | void initFilters(float bw);
74 | };
75 |
76 | #endif /* _RESAMPLER_H_ */
77 |
--------------------------------------------------------------------------------
/Transceiver52M/Synthesis.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Polyphase synthesis filter
3 | *
4 | * Copyright (C) 2012-2014 Tom Tsou
5 | * Copyright (C) 2015 Ettus Research LLC
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Affero General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Affero General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Affero General Public License
18 | * along with this program. If not, see .
19 | * See the COPYING file in the main directory for details.
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "Synthesis.h"
30 |
31 | extern "C" {
32 | #include "fft.h"
33 | #include "convolve.h"
34 | }
35 |
36 | static void interleave(float **in, size_t ilen,
37 | float *out, size_t m)
38 | {
39 | size_t i, n;
40 |
41 | for (i = 0; i < ilen; i++) {
42 | for (n = 0; n < m; n++) {
43 | out[2 * (i * m + n) + 0] = in[n][2 * i + 0];
44 | out[2 * (i * m + n) + 1] = in[n][2 * i + 1];
45 | }
46 | }
47 | }
48 |
49 | size_t Synthesis::inputLen() const
50 | {
51 | return blockLen;
52 | }
53 |
54 | size_t Synthesis::outputLen() const
55 | {
56 | return blockLen * m;
57 | }
58 |
59 | float *Synthesis::inputBuffer(size_t chan) const
60 | {
61 | if (chan >= m)
62 | return NULL;
63 |
64 | return hOutputs[chan];
65 | }
66 |
67 | bool Synthesis::resetBuffer(size_t chan)
68 | {
69 | if (chan >= m)
70 | return false;
71 |
72 | memset(hOutputs[chan], 0, blockLen * 2 * sizeof(float));
73 |
74 | return true;
75 | }
76 |
77 | /*
78 | * Implementation based on material found in:
79 | *
80 | * "harris, fred, Multirate Signal Processing, Upper Saddle River, NJ,
81 | * Prentice Hall, 2006."
82 | */
83 | bool Synthesis::rotate(float *out, size_t len)
84 | {
85 | size_t hSize = 2 * hLen * sizeof(float);
86 |
87 | if (!checkLen(blockLen, len)) {
88 | std::cout << "Length fail" << std::endl;
89 | exit(1);
90 | return false;
91 | }
92 |
93 | cxvec_fft(fftHandle);
94 |
95 | /*
96 | * Convolve through filterbank while applying and saving sample history
97 | */
98 | for (size_t i = 0; i < m; i++) {
99 | memcpy(&hInputs[i][2 * -hLen], hist[i], hSize);
100 | memcpy(hist[i], &hInputs[i][2 * (blockLen - hLen)], hSize);
101 |
102 | convolve_real(hInputs[i], blockLen,
103 | subFilters[i], hLen,
104 | hOutputs[i], blockLen,
105 | 0, blockLen);
106 | }
107 |
108 | /* Interleave into output vector */
109 | interleave(hOutputs, blockLen, out, m);
110 |
111 | return true;
112 | }
113 |
114 | Synthesis::Synthesis(size_t m, size_t blockLen, size_t hLen)
115 | : ChannelizerBase(m, blockLen, hLen)
116 | {
117 | }
118 |
119 | Synthesis::~Synthesis()
120 | {
121 | }
122 |
--------------------------------------------------------------------------------
/Transceiver52M/Synthesis.h:
--------------------------------------------------------------------------------
1 | #ifndef _SYNTHESIS_H_
2 | #define _SYNTHESIS_H_
3 |
4 | #include "ChannelizerBase.h"
5 |
6 | class Synthesis : public ChannelizerBase {
7 | public:
8 | /** Constructor for synthesis filterbank
9 | @param m number of physical channels
10 | @param blockLen number of samples per output of each iteration
11 | @param hLen number of taps in each constituent filter path
12 | */
13 | Synthesis(size_t m, size_t blockLen, size_t hLen = 16);
14 | ~Synthesis();
15 |
16 | /* Return required input and output buffer lengths */
17 | size_t inputLen() const;
18 | size_t outputLen() const;
19 |
20 | /** Rotate "output commutator" and drive samples through filterbank
21 | @param out complex output vector
22 | @param oLen number of samples in buffer (must match block length * m)
23 | @return false on error and true otherwise
24 | */
25 | bool rotate(float *out, size_t oLen);
26 |
27 | /** Get buffer for an input path
28 | @param chan channel number of filterbank
29 | @return NULL on error and pointer to buffer otherwise
30 | */
31 | float *inputBuffer(size_t chan) const;
32 | bool resetBuffer(size_t chan);
33 | };
34 |
35 | #endif /* _SYNTHESIS_H_ */
36 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/Makefile.am:
--------------------------------------------------------------------------------
1 | include $(top_srcdir)/Makefile.common
2 |
3 | SUBDIRS = common
4 | if ARCH_ARM
5 | SUBDIRS += arm
6 | else
7 | SUBDIRS += x86
8 | endif
9 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/Makefile.am:
--------------------------------------------------------------------------------
1 | if ARCH_ARM_A15
2 | ARCH_FLAGS = -mfpu=neon-vfpv4
3 | else
4 | ARCH_FLAGS = -mfpu=neon
5 | endif
6 |
7 | AM_CFLAGS = -Wall $(ARCH_FLAGS) -std=gnu99 -I${srcdir}/../common
8 | AM_CCASFLAGS = $(ARCH_FLAGS)
9 |
10 | noinst_LTLIBRARIES = libarch.la
11 |
12 | libarch_la_LIBADD = $(top_builddir)/Transceiver52M/arch/common/libarch_common.la
13 |
14 | libarch_la_SOURCES = \
15 | convert.c \
16 | convert_neon.S \
17 | convolve.c \
18 | convolve_neon.S \
19 | scale.c \
20 | scale_neon.S \
21 | mult.c \
22 | mult_neon.S
23 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/convert.c:
--------------------------------------------------------------------------------
1 | /*
2 | * NEON type conversions
3 | * Copyright (C) 2012, 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include "convert.h"
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | void neon_convert_ps_si16_4n(short *, const float *, const float *, int);
29 | void neon_convert_si16_ps_4n(float *, const short *, int);
30 |
31 | void convert_init(void) {
32 | }
33 |
34 | /* 4*N 16-bit signed integer conversion with remainder */
35 | static void neon_convert_si16_ps(float *out,
36 | const short *in,
37 | int len)
38 | {
39 | int start = len / 4 * 4;
40 |
41 | neon_convert_si16_ps_4n(out, in, len >> 2);
42 |
43 | for (int i = 0; i < len % 4; i++)
44 | out[start + i] = (float) in[start + i];
45 | }
46 |
47 | /* 4*N 16-bit signed integer conversion with remainder */
48 | static void neon_convert_ps_si16(short *out,
49 | const float *in,
50 | const float *scale,
51 | int len)
52 | {
53 | int start = len / 4 * 4;
54 |
55 | neon_convert_ps_si16_4n(out, in, scale, len >> 2);
56 |
57 | for (int i = 0; i < len % 4; i++)
58 | out[start + i] = (short) (in[start + i] * (*scale));
59 | }
60 |
61 | void convert_float_short(short *out, const float *in, float scale, int len)
62 | {
63 | #ifdef HAVE_NEON
64 | float q[4] = { scale, scale, scale, scale };
65 |
66 | if (len % 4)
67 | neon_convert_ps_si16(out, in, q, len);
68 | else
69 | neon_convert_ps_si16_4n(out, in, q, len >> 2);
70 | #else
71 | base_convert_float_short(out, in, scale, len);
72 | #endif
73 | }
74 |
75 | void convert_short_float(float *out, const short *in, int len)
76 | {
77 | #ifdef HAVE_NEON
78 | if (len % 4)
79 | neon_convert_si16_ps(out, in, len);
80 | else
81 | neon_convert_si16_ps_4n(out, in, len >> 2);
82 | #else
83 | base_convert_short_float(out, in, len);
84 | #endif
85 | }
86 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/convert_neon.S:
--------------------------------------------------------------------------------
1 | /*
2 | * NEON type conversions
3 | * Copyright (C) 2012, 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | .syntax unified
21 | .text
22 | .align 2
23 | .global neon_convert_ps_si16_4n
24 | .type neon_convert_ps_si16_4n, %function
25 | neon_convert_ps_si16_4n:
26 | vld1.32 {q1}, [r2]
27 | .loop_fltint:
28 | vld1.64 {d0-d1}, [r1]!
29 | vmul.f32 q0, q1
30 | vcvt.s32.f32 q2, q0
31 | vqmovn.s32 d0, q2
32 | vst1.64 {d0}, [r0]!
33 | subs r3, #1
34 | bne .loop_fltint
35 | bx lr
36 | .size neon_convert_ps_si16_4n, .-neon_convert_ps_si16_4n
37 | .text
38 | .align 2
39 | .global neon_convert_si16_ps_4n
40 | .type neon_convert_si16_ps_4n, %function
41 | neon_convert_si16_ps_4n:
42 | .loop_intflt:
43 | vld1.64 {d0}, [r1]!
44 | vmovl.s16 q1, d0
45 | vcvt.f32.s32 q0, q1
46 | vst1.64 {q0}, [r0]!
47 | subs r2, #1
48 | bne .loop_intflt
49 | bx lr
50 | .size neon_convert_si16_ps_4n, .-neon_convert_si16_ps_4n
51 | .section .note.GNU-stack,"",%progbits
52 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/convolve.c:
--------------------------------------------------------------------------------
1 | /*
2 | * NEON Convolution
3 | * Copyright (C) 2012, 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | /* Forward declarations from base implementation */
29 | int _base_convolve_real(float *x, int x_len,
30 | float *h, int h_len,
31 | float *y, int y_len,
32 | int start, int len);
33 |
34 | int _base_convolve_complex(float *x, int x_len,
35 | float *h, int h_len,
36 | float *y, int y_len,
37 | int start, int len);
38 |
39 | int bounds_check(int x_len, int h_len, int y_len,
40 | int start, int len);
41 |
42 | #ifdef HAVE_NEON
43 | /* Calls into NEON assembler */
44 | void neon_conv_real4(float *x, float *h, float *y, int len);
45 | void neon_conv_real8(float *x, float *h, float *y, int len);
46 | void neon_conv_real12(float *x, float *h, float *y, int len);
47 | void neon_conv_real16(float *x, float *h, float *y, int len);
48 | void neon_conv_real20(float *x, float *h, float *y, int len);
49 | void mac_cx_neon4(float *x, float *h, float *y, int len);
50 |
51 | /* Complex-complex convolution */
52 | static void neon_conv_cmplx_4n(float *x, float *h, float *y, int h_len, int len)
53 | {
54 | for (int i = 0; i < len; i++)
55 | mac_cx_neon4(&x[2 * i], h, &y[2 * i], h_len >> 2);
56 | }
57 | #endif
58 |
59 | /* API: Initalize convolve module */
60 | void convolve_init(void)
61 | {
62 | /* Stub */
63 | return;
64 | }
65 |
66 | /* API: Aligned complex-real */
67 | int convolve_real(float *x, int x_len,
68 | float *h, int h_len,
69 | float *y, int y_len,
70 | int start, int len)
71 | {
72 | void (*conv_func)(float *, float *, float *, int) = NULL;
73 |
74 | if (bounds_check(x_len, h_len, y_len, start, len) < 0)
75 | return -1;
76 |
77 | memset(y, 0, len * 2 * sizeof(float));
78 |
79 | #ifdef HAVE_NEON
80 | switch (h_len) {
81 | case 4:
82 | conv_func = neon_conv_real4;
83 | break;
84 | case 8:
85 | conv_func = neon_conv_real8;
86 | break;
87 | case 12:
88 | conv_func = neon_conv_real12;
89 | break;
90 | case 16:
91 | conv_func = neon_conv_real16;
92 | break;
93 | case 20:
94 | conv_func = neon_conv_real20;
95 | break;
96 | }
97 | #endif
98 | if (conv_func) {
99 | conv_func(&x[2 * (-(h_len - 1) + start)],
100 | h, y, len);
101 | } else {
102 | _base_convolve_real(x, x_len,
103 | h, h_len,
104 | y, y_len,
105 | start, len);
106 | }
107 |
108 | return len;
109 | }
110 |
111 |
112 | /* API: Aligned complex-complex */
113 | int convolve_complex(float *x, int x_len,
114 | float *h, int h_len,
115 | float *y, int y_len,
116 | int start, int len)
117 | {
118 | void (*conv_func)(float *, float *, float *, int, int) = NULL;
119 |
120 | if (bounds_check(x_len, h_len, y_len, start, len) < 0)
121 | return -1;
122 |
123 | memset(y, 0, len * 2 * sizeof(float));
124 |
125 | #ifdef HAVE_NEON
126 | if (!(h_len % 4))
127 | conv_func = neon_conv_cmplx_4n;
128 | #endif
129 | if (conv_func) {
130 | conv_func(&x[2 * (-(h_len - 1) + start)],
131 | h, y, h_len, len);
132 | } else {
133 | _base_convolve_complex(x, x_len,
134 | h, h_len,
135 | y, y_len,
136 | start, len);
137 | }
138 |
139 | return len;
140 | }
141 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/mult.c:
--------------------------------------------------------------------------------
1 | /*
2 | * NEON scaling
3 | * Copyright (C) 2012,2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | void neon_cmplx_mul_4n(float *, float *, float *, int);
29 |
30 | static void cmplx_mul_ps(float *out, float *a, float *b, int len)
31 | {
32 | float ai, aq, bi, bq;
33 |
34 | for (int i = 0; i < len; i++) {
35 | ai = a[2 * i + 0];
36 | aq = a[2 * i + 1];
37 |
38 | bi = b[2 * i + 0];
39 | bq = b[2 * i + 1];
40 |
41 | out[2 * i + 0] = ai * bi - aq * bq;
42 | out[2 * i + 1] = ai * bq + aq * bi;
43 | }
44 | }
45 |
46 | void mul_complex(float *out, float *a, float *b, int len)
47 | {
48 | #ifdef HAVE_NEON
49 | if (len % 4)
50 | cmplx_mul_ps(out, a, b, len);
51 | else
52 | neon_cmplx_mul_4n(out, a, b, len >> 2);
53 | #else
54 | cmplx_mul_ps(out, a, b, len);
55 | #endif
56 | }
57 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/mult_neon.S:
--------------------------------------------------------------------------------
1 | /*
2 | * NEON complex multiplication
3 | * Copyright (C) 2012,2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | .syntax unified
21 | .text
22 | .align 2
23 | .global neon_cmplx_mul_4n
24 | .type neon_cmplx_mul_4n, %function
25 | neon_cmplx_mul_4n:
26 | vpush {q4-q7}
27 | .loop_mul:
28 | vld2.32 {q0-q1}, [r1]!
29 | vld2.32 {q2-q3}, [r2]!
30 | vmul.f32 q4, q0, q2
31 | vmul.f32 q5, q1, q3
32 | vmul.f32 q6, q0, q3
33 | vmul.f32 q7, q2, q1
34 | vsub.f32 q8, q4, q5
35 | vadd.f32 q9, q6, q7
36 | vst2.32 {q8-q9}, [r0]!
37 | subs r3, #1
38 | bne .loop_mul
39 | vpop {q4-q7}
40 | bx lr
41 | .size neon_cmplx_mul_4n, .-neon_cmplx_mul_4n
42 | .section .note.GNU-stack,"",%progbits
43 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/scale.c:
--------------------------------------------------------------------------------
1 | /*
2 | * NEON scaling
3 | * Copyright (C) 2012,2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | void neon_scale_4n(float *, float *, float *, int);
29 |
30 | static void scale_ps(float *out, float *in, float *scale, int len)
31 | {
32 | float ai, aq, bi, bq;
33 |
34 | bi = scale[0];
35 | bq = scale[1];
36 |
37 | for (int i = 0; i < len; i++) {
38 | ai = in[2 * i + 0];
39 | aq = in[2 * i + 1];
40 |
41 | out[2 * i + 0] = ai * bi - aq * bq;
42 | out[2 * i + 1] = ai * bq + aq * bi;
43 | }
44 | }
45 |
46 | void scale_complex(float *out, float *in, float* scale, int len)
47 | {
48 | #ifdef HAVE_NEON
49 | if (len % 4)
50 | scale_ps(out, in, scale, len);
51 | else
52 | neon_scale_4n(in, scale, out, len >> 2);
53 | #else
54 | scale_ps(out, in, scale, len);
55 | #endif
56 | }
57 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/arm/scale_neon.S:
--------------------------------------------------------------------------------
1 | /*
2 | * ARM NEON Scaling
3 | * Copyright (C) 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | .syntax unified
21 | .text
22 | .align 2
23 | .global neon_scale_4n
24 | .type neon_scale_4n, %function
25 | neon_scale_4n:
26 | push {r4, lr}
27 | ldr r4, =32
28 |
29 | vld1.64 d0, [r1]
30 | vmov.32 s4, s1
31 | vmov.32 s1, s0
32 | vmov.64 d1, d0
33 | vmov.32 s5, s4
34 | vmov.64 d3, d2
35 | .loop_mul_const:
36 | vld2.32 {q2-q3}, [r0], r4
37 |
38 | vmul.f32 q8, q0, q2
39 | vmul.f32 q9, q1, q3
40 | vmul.f32 q10, q0, q3
41 | vmul.f32 q11, q1, q2
42 | vsub.f32 q8, q8, q9
43 | vadd.f32 q9, q10, q11
44 |
45 | vst2.32 {q8-q9}, [r2]!
46 | subs r3, #1
47 | bne .loop_mul_const
48 | pop {r4, pc}
49 | .size neon_scale_4n, .-neon_scale_4n
50 | .section .note.GNU-stack,"",%progbits
51 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/Makefile.am:
--------------------------------------------------------------------------------
1 | AM_CFLAGS = -Wall -std=gnu99
2 |
3 | noinst_LTLIBRARIES = libarch_common.la
4 |
5 | noinst_HEADERS = \
6 | convolve.h \
7 | convert.h \
8 | scale.h \
9 | mult.h \
10 | fft.h
11 |
12 | libarch_common_la_SOURCES = \
13 | convolve_base.c \
14 | convert_base.c \
15 | fft.c
16 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/convert.h:
--------------------------------------------------------------------------------
1 | #ifndef _CONVERT_H_
2 | #define _CONVERT_H_
3 |
4 | void convert_float_short(short *out, const float *in, float scale, int len);
5 |
6 | void convert_short_float(float *out, const short *in, int len);
7 |
8 | void base_convert_float_short(short *out, const float *in,
9 | float scale, int len);
10 |
11 | void base_convert_short_float(float *out, const short *in, int len);
12 |
13 | void convert_init(void);
14 |
15 | #endif /* _CONVERT_H_ */
16 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/convert_base.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Conversion
3 | * Copyright (C) 2012, 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "convert.h"
21 |
22 | void base_convert_float_short(short *out, const float *in,
23 | float scale, int len)
24 | {
25 | for (int i = 0; i < len; i++)
26 | out[i] = in[i] * scale;
27 | }
28 |
29 | void base_convert_short_float(float *out, const short *in, int len)
30 | {
31 | for (int i = 0; i < len; i++)
32 | out[i] = in[i];
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/convolve.h:
--------------------------------------------------------------------------------
1 | #ifndef _CONVOLVE_H_
2 | #define _CONVOLVE_H_
3 |
4 | void *convolve_h_alloc(size_t num);
5 |
6 | int convolve_real(const float *x, int x_len,
7 | const float *h, int h_len,
8 | float *y, int y_len,
9 | int start, int len);
10 |
11 | int convolve_complex(const float *x, int x_len,
12 | const float *h, int h_len,
13 | float *y, int y_len,
14 | int start, int len);
15 |
16 | int base_convolve_real(const float *x, int x_len,
17 | const float *h, int h_len,
18 | float *y, int y_len,
19 | int start, int len);
20 |
21 | int base_convolve_complex(const float *x, int x_len,
22 | const float *h, int h_len,
23 | float *y, int y_len,
24 | int start, int len);
25 |
26 | void convolve_init(void);
27 |
28 | #endif /* _CONVOLVE_H_ */
29 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/convolve_base.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Convolution
3 | * Copyright (C) 2012, 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | /* Base multiply and accumulate complex-real */
29 | static void mac_real(const float *x, const float *h, float *y)
30 | {
31 | y[0] += x[0] * h[0];
32 | y[1] += x[1] * h[0];
33 | }
34 |
35 | /* Base multiply and accumulate complex-complex */
36 | static void mac_cmplx(const float *x, const float *h, float *y)
37 | {
38 | y[0] += x[0] * h[0] - x[1] * h[1];
39 | y[1] += x[0] * h[1] + x[1] * h[0];
40 | }
41 |
42 | /* Base vector complex-complex multiply and accumulate */
43 | static void mac_real_vec_n(const float *x, const float *h, float *y,
44 | int len)
45 | {
46 | for (int i=0; i x_len) || (len > y_len) || (x_len < h_len)) {
100 | fprintf(stderr, "Convolve: Boundary exception\n");
101 | fprintf(stderr, "start: %i, len: %i, x: %i, h: %i, y: %i\n",
102 | start, len, x_len, h_len, y_len);
103 | return -1;
104 | }
105 |
106 | return 0;
107 | }
108 |
109 | /* API: Non-aligned (no SSE) complex-real */
110 | int base_convolve_real(const float *x, int x_len,
111 | const float *h, int h_len,
112 | float *y, int y_len,
113 | int start, int len)
114 | {
115 | if (bounds_check(x_len, h_len, y_len, start, len) < 0)
116 | return -1;
117 |
118 | memset(y, 0, len * 2 * sizeof(float));
119 |
120 | return _base_convolve_real(x, x_len,
121 | h, h_len,
122 | y, y_len,
123 | start, len);
124 | }
125 |
126 | /* API: Non-aligned (no SSE) complex-complex */
127 | int base_convolve_complex(const float *x, int x_len,
128 | const float *h, int h_len,
129 | float *y, int y_len,
130 | int start, int len)
131 | {
132 | if (bounds_check(x_len, h_len, y_len, start, len) < 0)
133 | return -1;
134 |
135 | memset(y, 0, len * 2 * sizeof(float));
136 |
137 | return _base_convolve_complex(x, x_len,
138 | h, h_len,
139 | y, y_len,
140 | start, len);
141 | }
142 |
143 | /* Aligned filter tap allocation */
144 | void *convolve_h_alloc(size_t len)
145 | {
146 | #ifdef HAVE_SSE3
147 | return memalign(16, len * 2 * sizeof(float));
148 | #else
149 | return malloc(len * 2 * sizeof(float));
150 | #endif
151 | }
152 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/fft.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Fast Fourier transform
3 | *
4 | * Copyright (C) 2012 Tom Tsou
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program; if not, see .
18 | * See the COPYING file in the main directory for details.
19 | */
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "fft.h"
27 |
28 | struct fft_hdl {
29 | float *fft_in;
30 | float *fft_out;
31 | int len;
32 | fftwf_plan fft_plan;
33 | };
34 |
35 | /*! \brief Initialize FFT backend
36 | * \param[in] reverse FFT direction
37 | * \param[in] m FFT length
38 | * \param[in] istride input stride count
39 | * \param[in] ostride output stride count
40 | * \param[in] in input buffer (FFTW aligned)
41 | * \param[in] out output buffer (FFTW aligned)
42 | * \param[in] ooffset initial offset into output buffer
43 | *
44 | * If the reverse is non-NULL, then an inverse FFT will be used. This is a
45 | * wrapper for advanced non-contiguous FFTW usage. See FFTW documentation for
46 | * further details.
47 | *
48 | * http://www.fftw.org/doc/Advanced-Complex-DFTs.html
49 | *
50 | * It is currently unknown how the offset of the output buffer affects FFTW
51 | * memory alignment.
52 | */
53 | struct fft_hdl *init_fft(int reverse, int m, int istride, int ostride,
54 | float *in, float *out, int ooffset)
55 | {
56 | int rank = 1;
57 | int n[] = { m };
58 | int howmany = istride;
59 | int idist = 1;
60 | int odist = 1;
61 | int *inembed = n;
62 | int *onembed = n;
63 | fftwf_complex *obuffer, *ibuffer;
64 |
65 | struct fft_hdl *hdl = (struct fft_hdl *) malloc(sizeof(struct fft_hdl));
66 | if (!hdl)
67 | return NULL;
68 |
69 | int direction = FFTW_FORWARD;
70 | if (reverse)
71 | direction = FFTW_BACKWARD;
72 |
73 | ibuffer = (fftwf_complex *) in;
74 | obuffer = (fftwf_complex *) out + ooffset;
75 |
76 | hdl->fft_in = in;
77 | hdl->fft_out = out;
78 | hdl->fft_plan = fftwf_plan_many_dft(rank, n, howmany,
79 | ibuffer, inembed, istride, idist,
80 | obuffer, onembed, ostride, odist,
81 | direction, FFTW_MEASURE);
82 | return hdl;
83 | }
84 |
85 | void *fft_malloc(size_t size)
86 | {
87 | return fftwf_malloc(size);
88 | }
89 |
90 | void fft_free(void *ptr)
91 | {
92 | free(ptr);
93 | }
94 |
95 | /*! \brief Free FFT backend resources
96 | */
97 | void free_fft(struct fft_hdl *hdl)
98 | {
99 | fftwf_destroy_plan(hdl->fft_plan);
100 | free(hdl);
101 | }
102 |
103 | /*! \brief Run multiple DFT operations with the initialized plan
104 | * \param[in] hdl handle to an intitialized fft struct
105 | *
106 | * Input and output buffers are configured with init_fft().
107 | */
108 | int cxvec_fft(struct fft_hdl *hdl)
109 | {
110 | fftwf_execute(hdl->fft_plan);
111 | return 0;
112 | }
113 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/fft.h:
--------------------------------------------------------------------------------
1 | #ifndef _FFT_H_
2 | #define _FFT_H_
3 |
4 | struct fft_hdl;
5 |
6 | struct fft_hdl *init_fft(int reverse, int m, int istride, int ostride,
7 | float *in, float *out, int ooffset);
8 | void *fft_malloc(size_t size);
9 | void fft_free(void *ptr);
10 | void free_fft(struct fft_hdl *hdl);
11 | int cxvec_fft(struct fft_hdl *hdl);
12 |
13 | #endif /* _FFT_H_ */
14 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/mult.h:
--------------------------------------------------------------------------------
1 | #ifndef _MULT_H_
2 | #define _MULT_H_
3 |
4 | void mul_complex(float *out, float *a, float *b, int len);
5 |
6 | #endif /* _MULT_H_ */
7 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/common/scale.h:
--------------------------------------------------------------------------------
1 | #ifndef _SCALE_H_
2 | #define _SCALE_H_
3 |
4 | void scale_complex(float *out, float *in, float *scale, int len);
5 |
6 | #endif /* _SCALE_H_ */
7 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/x86/Makefile.am:
--------------------------------------------------------------------------------
1 | AM_CFLAGS = -Wall -std=gnu99 -I${srcdir}/../common
2 |
3 | noinst_LTLIBRARIES = libarch.la
4 | noinst_LTLIBRARIES += libarch_sse_3.la
5 | noinst_LTLIBRARIES += libarch_sse_4_1.la
6 |
7 | noinst_HEADERS = \
8 | convert_sse_3.h \
9 | convert_sse_4_1.h \
10 | convolve_sse_3.h
11 |
12 | libarch_la_LIBADD = $(top_builddir)/Transceiver52M/arch/common/libarch_common.la
13 |
14 | # SSE 3 specific code
15 | if HAVE_SSE3
16 | libarch_sse_3_la_SOURCES = \
17 | convert_sse_3.c \
18 | convolve_sse_3.c
19 | libarch_sse_3_la_CFLAGS = $(AM_CFLAGS) -msse3
20 | libarch_la_LIBADD += libarch_sse_3.la
21 | endif
22 |
23 | # SSE 4.1 specific code
24 | if HAVE_SSE4_1
25 | libarch_sse_4_1_la_SOURCES = \
26 | convert_sse_4_1.c
27 | libarch_sse_4_1_la_CFLAGS = $(AM_CFLAGS) -msse4.1
28 | libarch_la_LIBADD += libarch_sse_4_1.la
29 | endif
30 |
31 | libarch_la_SOURCES = \
32 | convert.c \
33 | convolve.c
34 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/x86/convert.c:
--------------------------------------------------------------------------------
1 | /*
2 | * SSE type conversions
3 | * Copyright (C) 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include "convert.h"
23 | #include "convert_sse_3.h"
24 | #include "convert_sse_4_1.h"
25 |
26 | #ifdef HAVE_CONFIG_H
27 | #include "config.h"
28 | #endif
29 |
30 | /* Architecture dependant function pointers */
31 | struct convert_cpu_context {
32 | void (*convert_si16_ps_16n) (float *, const short *, int);
33 | void (*convert_si16_ps) (float *, const short *, int);
34 | void (*convert_scale_ps_si16_16n)(short *, const float *, float, int);
35 | void (*convert_scale_ps_si16_8n)(short *, const float *, float, int);
36 | void (*convert_scale_ps_si16)(short *, const float *, float, int);
37 | };
38 |
39 | static struct convert_cpu_context c;
40 |
41 | void convert_init(void)
42 | {
43 | c.convert_scale_ps_si16_16n = base_convert_float_short;
44 | c.convert_scale_ps_si16_8n = base_convert_float_short;
45 | c.convert_scale_ps_si16 = base_convert_float_short;
46 | c.convert_si16_ps_16n = base_convert_short_float;
47 | c.convert_si16_ps = base_convert_short_float;
48 |
49 | #ifdef HAVE___BUILTIN_CPU_SUPPORTS
50 | #ifdef HAVE_SSE4_1
51 | if (__builtin_cpu_supports("sse4.1")) {
52 | c.convert_si16_ps_16n = &_sse_convert_si16_ps_16n;
53 | c.convert_si16_ps = &_sse_convert_si16_ps;
54 | }
55 | #endif
56 |
57 | #ifdef HAVE_SSE3
58 | if (__builtin_cpu_supports("sse3")) {
59 | c.convert_scale_ps_si16_16n = _sse_convert_scale_ps_si16_16n;
60 | c.convert_scale_ps_si16_8n = _sse_convert_scale_ps_si16_8n;
61 | c.convert_scale_ps_si16 = _sse_convert_scale_ps_si16;
62 | }
63 | #endif
64 | #endif
65 | }
66 |
67 | void convert_float_short(short *out, const float *in, float scale, int len)
68 | {
69 | if (!(len % 16))
70 | c.convert_scale_ps_si16_16n(out, in, scale, len);
71 | else if (!(len % 8))
72 | c.convert_scale_ps_si16_8n(out, in, scale, len);
73 | else
74 | c.convert_scale_ps_si16(out, in, scale, len);
75 | }
76 |
77 | void convert_short_float(float *out, const short *in, int len)
78 | {
79 | if (!(len % 16))
80 | c.convert_si16_ps_16n(out, in, len);
81 | else
82 | c.convert_si16_ps(out, in, len);
83 | }
84 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/x86/convert_sse_3.c:
--------------------------------------------------------------------------------
1 | /*
2 | * SSE type conversions
3 | * Copyright (C) 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include "convert_sse_3.h"
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | #ifdef HAVE_SSE3
29 | #include
30 | #include
31 |
32 | /* 8*N single precision floats scaled and converted to 16-bit signed integer */
33 | void _sse_convert_scale_ps_si16_8n(short *restrict out,
34 | const float *restrict in,
35 | float scale, int len)
36 | {
37 | __m128 m0, m1, m2;
38 | __m128i m4, m5;
39 |
40 | for (int i = 0; i < len / 8; i++) {
41 | /* Load (unaligned) packed floats */
42 | m0 = _mm_loadu_ps(&in[8 * i + 0]);
43 | m1 = _mm_loadu_ps(&in[8 * i + 4]);
44 | m2 = _mm_load1_ps(&scale);
45 |
46 | /* Scale */
47 | m0 = _mm_mul_ps(m0, m2);
48 | m1 = _mm_mul_ps(m1, m2);
49 |
50 | /* Convert */
51 | m4 = _mm_cvtps_epi32(m0);
52 | m5 = _mm_cvtps_epi32(m1);
53 |
54 | /* Pack and store */
55 | m5 = _mm_packs_epi32(m4, m5);
56 | _mm_storeu_si128((__m128i *) & out[8 * i], m5);
57 | }
58 | }
59 |
60 | /* 8*N single precision floats scaled and converted with remainder */
61 | void _sse_convert_scale_ps_si16(short *restrict out,
62 | const float *restrict in, float scale, int len)
63 | {
64 | int start = len / 8 * 8;
65 |
66 | _sse_convert_scale_ps_si16_8n(out, in, scale, len);
67 |
68 | for (int i = 0; i < len % 8; i++)
69 | out[start + i] = in[start + i] * scale;
70 | }
71 |
72 | /* 16*N single precision floats scaled and converted to 16-bit signed integer */
73 | void _sse_convert_scale_ps_si16_16n(short *restrict out,
74 | const float *restrict in,
75 | float scale, int len)
76 | {
77 | __m128 m0, m1, m2, m3, m4;
78 | __m128i m5, m6, m7, m8;
79 |
80 | for (int i = 0; i < len / 16; i++) {
81 | /* Load (unaligned) packed floats */
82 | m0 = _mm_loadu_ps(&in[16 * i + 0]);
83 | m1 = _mm_loadu_ps(&in[16 * i + 4]);
84 | m2 = _mm_loadu_ps(&in[16 * i + 8]);
85 | m3 = _mm_loadu_ps(&in[16 * i + 12]);
86 | m4 = _mm_load1_ps(&scale);
87 |
88 | /* Scale */
89 | m0 = _mm_mul_ps(m0, m4);
90 | m1 = _mm_mul_ps(m1, m4);
91 | m2 = _mm_mul_ps(m2, m4);
92 | m3 = _mm_mul_ps(m3, m4);
93 |
94 | /* Convert */
95 | m5 = _mm_cvtps_epi32(m0);
96 | m6 = _mm_cvtps_epi32(m1);
97 | m7 = _mm_cvtps_epi32(m2);
98 | m8 = _mm_cvtps_epi32(m3);
99 |
100 | /* Pack and store */
101 | m5 = _mm_packs_epi32(m5, m6);
102 | m7 = _mm_packs_epi32(m7, m8);
103 | _mm_storeu_si128((__m128i *) & out[16 * i + 0], m5);
104 | _mm_storeu_si128((__m128i *) & out[16 * i + 8], m7);
105 | }
106 | }
107 | #endif
108 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/x86/convert_sse_3.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SSE type conversions
3 | * Copyright (C) 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #pragma once
21 |
22 | /* 8*N single precision floats scaled and converted to 16-bit signed integer */
23 | void _sse_convert_scale_ps_si16_8n(short *restrict out,
24 | const float *restrict in,
25 | float scale, int len);
26 |
27 | /* 8*N single precision floats scaled and converted with remainder */
28 | void _sse_convert_scale_ps_si16(short *restrict out,
29 | const float *restrict in, float scale, int len);
30 |
31 | /* 16*N single precision floats scaled and converted to 16-bit signed integer */
32 | void _sse_convert_scale_ps_si16_16n(short *restrict out,
33 | const float *restrict in,
34 | float scale, int len);
35 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/x86/convert_sse_4_1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * SSE type conversions
3 | * Copyright (C) 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include "convert_sse_4_1.h"
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | #ifdef HAVE_SSE4_1
29 | #include
30 |
31 | /* 16*N 16-bit signed integer converted to single precision floats */
32 | void _sse_convert_si16_ps_16n(float *restrict out,
33 | const short *restrict in, int len)
34 | {
35 | __m128i m0, m1, m2, m3, m4, m5;
36 | __m128 m6, m7, m8, m9;
37 |
38 | for (int i = 0; i < len / 16; i++) {
39 | /* Load (unaligned) packed floats */
40 | m0 = _mm_loadu_si128((__m128i *) & in[16 * i + 0]);
41 | m1 = _mm_loadu_si128((__m128i *) & in[16 * i + 8]);
42 |
43 | /* Unpack */
44 | m2 = _mm_cvtepi16_epi32(m0);
45 | m4 = _mm_cvtepi16_epi32(m1);
46 | m0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2));
47 | m1 = _mm_shuffle_epi32(m1, _MM_SHUFFLE(1, 0, 3, 2));
48 | m3 = _mm_cvtepi16_epi32(m0);
49 | m5 = _mm_cvtepi16_epi32(m1);
50 |
51 | /* Convert */
52 | m6 = _mm_cvtepi32_ps(m2);
53 | m7 = _mm_cvtepi32_ps(m3);
54 | m8 = _mm_cvtepi32_ps(m4);
55 | m9 = _mm_cvtepi32_ps(m5);
56 |
57 | /* Store */
58 | _mm_storeu_ps(&out[16 * i + 0], m6);
59 | _mm_storeu_ps(&out[16 * i + 4], m7);
60 | _mm_storeu_ps(&out[16 * i + 8], m8);
61 | _mm_storeu_ps(&out[16 * i + 12], m9);
62 | }
63 | }
64 |
65 | /* 16*N 16-bit signed integer conversion with remainder */
66 | void _sse_convert_si16_ps(float *restrict out,
67 | const short *restrict in, int len)
68 | {
69 | int start = len / 16 * 16;
70 |
71 | _sse_convert_si16_ps_16n(out, in, len);
72 |
73 | for (int i = 0; i < len % 16; i++)
74 | out[start + i] = in[start + i];
75 | }
76 |
77 | #endif
78 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/x86/convert_sse_4_1.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SSE type conversions
3 | * Copyright (C) 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #pragma once
21 |
22 | /* 16*N 16-bit signed integer converted to single precision floats */
23 | void _sse_convert_si16_ps_16n(float *restrict out,
24 | const short *restrict in, int len);
25 |
26 | /* 16*N 16-bit signed integer conversion with remainder */
27 | void _sse_convert_si16_ps(float *restrict out,
28 | const short *restrict in, int len);
29 |
--------------------------------------------------------------------------------
/Transceiver52M/arch/x86/convolve_sse_3.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SSE Convolution
3 | * Copyright (C) 2012, 2013 Thomas Tsou
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #pragma once
21 |
22 | /* 4-tap SSE complex-real convolution */
23 | void sse_conv_real4(const float *x, int x_len,
24 | const float *h, int h_len,
25 | float *y, int y_len,
26 | int start, int len);
27 |
28 | /* 8-tap SSE complex-real convolution */
29 | void sse_conv_real8(const float *x, int x_len,
30 | const float *h, int h_len,
31 | float *y, int y_len,
32 | int start, int len);
33 |
34 | /* 12-tap SSE complex-real convolution */
35 | void sse_conv_real12(const float *x, int x_len,
36 | const float *h, int h_len,
37 | float *y, int y_len,
38 | int start, int len);
39 |
40 | /* 16-tap SSE complex-real convolution */
41 | void sse_conv_real16(const float *x, int x_len,
42 | const float *h, int h_len,
43 | float *y, int y_len,
44 | int start, int len);
45 |
46 | /* 20-tap SSE complex-real convolution */
47 | void sse_conv_real20(const float *x, int x_len,
48 | const float *h, int h_len,
49 | float *y, int y_len,
50 | int start, int len);
51 |
52 | /* 4*N-tap SSE complex-real convolution */
53 | void sse_conv_real4n(const float *x, int x_len,
54 | const float *h, int h_len,
55 | float *y, int y_len,
56 | int start, int len);
57 |
58 | /* 4*N-tap SSE complex-complex convolution */
59 | void sse_conv_cmplx_4n(const float *x, int x_len,
60 | const float *h, int h_len,
61 | float *y, int y_len,
62 | int start, int len);
63 |
64 | /* 8*N-tap SSE complex-complex convolution */
65 | void sse_conv_cmplx_8n(const float *x, int x_len,
66 | const float *h, int h_len,
67 | float *y, int y_len,
68 | int start, int len);
69 |
--------------------------------------------------------------------------------
/Transceiver52M/device/Makefile.am:
--------------------------------------------------------------------------------
1 | include $(top_srcdir)/Makefile.common
2 |
3 | noinst_HEADERS = radioDevice.h
4 |
5 | SUBDIRS =
6 |
7 | if DEVICE_USRP1
8 | SUBDIRS += usrp1
9 | endif
10 |
11 | if DEVICE_UHD
12 | SUBDIRS += uhd
13 | endif
14 |
15 | if DEVICE_LMS
16 | SUBDIRS += lms
17 | endif
18 |
--------------------------------------------------------------------------------
/Transceiver52M/device/lms/Makefile.am:
--------------------------------------------------------------------------------
1 | include $(top_srcdir)/Makefile.common
2 |
3 | AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/..
4 | AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LMS_CFLAGS)
5 |
6 | noinst_HEADERS = LMSDevice.h
7 |
8 | noinst_LTLIBRARIES = libdevice.la
9 |
10 | libdevice_la_SOURCES = LMSDevice.cpp
11 |
--------------------------------------------------------------------------------
/Transceiver52M/device/uhd/Makefile.am:
--------------------------------------------------------------------------------
1 | include $(top_srcdir)/Makefile.common
2 |
3 | AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/..
4 | AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(UHD_CFLAGS)
5 |
6 | noinst_LTLIBRARIES = libdevice.la
7 |
8 | libdevice_la_SOURCES = UHDDevice.cpp
9 |
--------------------------------------------------------------------------------
/Transceiver52M/device/usrp1/Makefile.am:
--------------------------------------------------------------------------------
1 | include $(top_srcdir)/Makefile.common
2 |
3 | AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/..
4 | AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(USRP_CFLAGS)
5 |
6 | noinst_HEADERS = USRPDevice.h
7 |
8 | noinst_LTLIBRARIES = libdevice.la
9 |
10 | libdevice_la_SOURCES = USRPDevice.cpp
11 |
--------------------------------------------------------------------------------
/Transceiver52M/laurent.m:
--------------------------------------------------------------------------------
1 | %
2 | % Laurent decomposition of GMSK signals
3 | % Generates C0, C1, and C2 pulse shapes
4 | %
5 | % Pierre Laurent, "Exact and Approximate Construction of Digital Phase
6 | % Modulations by Superposition of Amplitude Modulated Pulses", IEEE
7 | % Transactions of Communications, Vol. 34, No. 2, Feb 1986.
8 | %
9 | % Author: Thomas Tsou
10 | %
11 |
12 | % Modulation parameters
13 | oversamp = 16;
14 | L = 3;
15 | f = 270.83333e3;
16 | T = 1/f;
17 | h = 0.5;
18 | BT = 0.30;
19 | B = BT / T;
20 |
21 | % Generate sampling points for L symbol periods
22 | t = -(L*T/2):T/oversamp:(L*T/2);
23 | t = t(1:end-1) + (T/oversamp/2);
24 |
25 | % Generate Gaussian pulse
26 | g = qfunc(2*pi*B*(t - T/2)/(log(2)^.5)) - qfunc(2*pi*B*(t + T/2)/(log(2)^.5));
27 | g = g / sum(g) * pi/2;
28 | g = [0 g];
29 |
30 | % Integrate phase
31 | q = 0;
32 | for i = 1:size(g,2);
33 | q(i) = sum(g(1:i));
34 | end
35 |
36 | % Compute two sided "generalized phase pulse" function
37 | s = 0;
38 | for i = 1:size(g,2);
39 | s(i) = sin(q(i)) / sin(pi*h);
40 | end
41 | for i = (size(g,2) + 1):(2 * size(g,2) - 1);
42 | s(i) = sin(pi*h - q(i - (size(g,2) - 1))) / sin(pi*h);
43 | end
44 |
45 | % Compute C0 pulse: valid for all L values
46 | c0 = s(1:end-(oversamp*(L-1)));
47 | for i = 1:L-1;
48 | c0 = c0 .* s((1 + i*oversamp):end-(oversamp*(L - 1 - i)));
49 | end
50 |
51 | % Compute C1 pulse: valid for L = 3 only!
52 | % C1 = S0 * S4 * S2
53 | c1 = s(1:end-(oversamp*(4)));
54 | c1 = c1 .* s((1 + 4*oversamp):end-(oversamp*(4 - 1 - 3)));
55 | c1 = c1 .* s((1 + 2*oversamp):end-(oversamp*(4 - 1 - 1)));
56 |
57 | % Compute C2 pulse: valid for L = 3 only!
58 | % C2 = S0 * S1 * S5
59 | c2 = s(1:end-(oversamp*(5)));
60 | c2 = c2 .* s((1 + 1*oversamp):end-(oversamp*(5 - 1 - 0)));
61 | c2 = c2 .* s((1 + 5*oversamp):end-(oversamp*(5 - 1 - 4)));
62 |
63 | % Plot C0, C1, C2 Laurent pulse series
64 | figure(1);
65 | hold off;
66 | plot((0:size(c0,2)-1)/oversamp - 2,c0, 'b');
67 | hold on;
68 | plot((0:size(c1,2)-1)/oversamp - 2,c1, 'r');
69 | plot((0:size(c2,2)-1)/oversamp - 2,c2, 'g');
70 |
71 | % Generate OpenBTS pulse
72 | numSamples = size(c0,2);
73 | centerPoint = (numSamples - 1)/2;
74 | i = ((0:numSamples) - centerPoint) / oversamp;
75 | xP = .96*exp(-1.1380*i.^2 - 0.527*i.^4);
76 | xP = xP / max(xP) * max(c0);
77 |
78 | % Plot C0 pulse compared to OpenBTS pulse
79 | figure(2);
80 | hold off;
81 | plot((0:size(c0,2)-1)/oversamp, c0, 'b');
82 | hold on;
83 | plot((0:size(xP,2)-1)/oversamp, xP, 'r');
84 |
--------------------------------------------------------------------------------
/Transceiver52M/pulseApproximate.m:
--------------------------------------------------------------------------------
1 | pp = [0 0 0.015 0.18 0.7 0.96 0.7 0.18 0.015 0 0];
2 | t = -2.5:0.5:2.5;
3 |
4 | v = -0.000:-0.001:-1.999;
5 |
6 |
7 | for ix1 = 1:length(v),
8 | disp(ix1);
9 | for ix2 = 1:length(v),
10 | p = exp(v(ix1)*t.^2+v(ix2)*t.^4);
11 | r(ix1,ix2) = norm(p./max(abs(p)) - pp./max(abs(pp)));
12 | end;
13 | end;
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Transceiver52M/radioBuffer.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | class RadioBuffer {
6 | public:
7 | RadioBuffer(size_t numSegments, size_t segmentLen,
8 | size_t hLen, bool outDirection);
9 |
10 | ~RadioBuffer();
11 |
12 | const size_t getSegmentLen() { return segmentLen; }
13 | const size_t getNumSegments() { return numSegments; }
14 | const size_t getAvailSamples() { return availSamples; }
15 | const size_t getAvailSegments() { return availSamples / segmentLen; }
16 |
17 | const size_t getFreeSamples()
18 | {
19 | return bufferLen - availSamples;
20 | }
21 |
22 | const size_t getFreeSegments()
23 | {
24 | return getFreeSamples() / segmentLen;
25 | }
26 |
27 | void reset();
28 |
29 | /* Output direction */
30 | const float *getReadSegment();
31 | bool write(const float *wr, size_t len);
32 | bool zero(size_t len);
33 |
34 | /* Input direction */
35 | float *getWriteSegment();
36 | bool zeroWriteSegment();
37 | bool read(float *rd, size_t len);
38 |
39 | private:
40 | size_t writeIndex, readIndex, availSamples;
41 | size_t bufferLen, numSegments, segmentLen, hLen;
42 | float *buffer;
43 | std::vector segments;
44 | bool outDirection;
45 | };
46 |
--------------------------------------------------------------------------------
/Transceiver52M/radioClock.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Written by Thomas Tsou
3 | * Based on code by Harvind S Samra
4 | *
5 | * Copyright 2011 Free Software Foundation, Inc.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Affero General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Affero General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Affero General Public License
18 | * along with this program. If not, see .
19 | * See the COPYING file in the main directory for details.
20 | */
21 |
22 | #include "radioClock.h"
23 |
24 | void RadioClock::set(const GSM::Time& wTime)
25 | {
26 | ScopedLock lock(mLock);
27 | mClock = wTime;
28 | updateSignal.signal();
29 | }
30 |
31 | void RadioClock::incTN()
32 | {
33 | ScopedLock lock(mLock);
34 | mClock.incTN();
35 | updateSignal.signal();
36 | }
37 |
38 | GSM::Time RadioClock::get()
39 | {
40 | ScopedLock lock(mLock);
41 | GSM::Time retVal = mClock;
42 | return retVal;
43 | }
44 |
45 | void RadioClock::wait()
46 | {
47 | ScopedLock lock(mLock);
48 | updateSignal.wait(mLock,1);
49 | }
50 |
--------------------------------------------------------------------------------
/Transceiver52M/radioClock.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Written by Thomas Tsou
3 | * Based on code by Harvind S Samra
4 | *
5 | * Copyright 2011 Free Software Foundation, Inc.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Affero General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Affero General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Affero General Public License
18 | * along with this program. If not, see .
19 | * See the COPYING file in the main directory for details.
20 | */
21 |
22 | #ifndef RADIOCLOCK_H
23 | #define RADIOCLOCK_H
24 |
25 | #include "GSMCommon.h"
26 |
27 | class RadioClock {
28 | public:
29 | void set(const GSM::Time& wTime);
30 | void incTN();
31 | GSM::Time get();
32 | void wait();
33 |
34 | private:
35 | GSM::Time mClock;
36 | Mutex mLock;
37 | Signal updateSignal;
38 | };
39 |
40 | #endif /* RADIOCLOCK_H */
41 |
--------------------------------------------------------------------------------
/Transceiver52M/radioVector.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Written by Thomas Tsou
3 | * Based on code by Harvind S Samra
4 | *
5 | * Copyright 2011 Free Software Foundation, Inc.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Affero General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Affero General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Affero General Public License
18 | * along with this program. If not, see .
19 | * See the COPYING file in the main directory for details.
20 | */
21 |
22 | #include "radioVector.h"
23 |
24 | radioVector::radioVector(GSM::Time &time, size_t size,
25 | size_t start, size_t chans)
26 | : vectors(chans), mTime(time)
27 | {
28 | for (size_t i = 0; i < vectors.size(); i++)
29 | vectors[i] = new signalVector(size, start);
30 | }
31 |
32 | radioVector::radioVector(GSM::Time& wTime, signalVector *vector)
33 | : vectors(1), mTime(wTime)
34 | {
35 | vectors[0] = vector;
36 | }
37 |
38 | radioVector::~radioVector()
39 | {
40 | for (size_t i = 0; i < vectors.size(); i++)
41 | delete vectors[i];
42 | }
43 |
44 | GSM::Time radioVector::getTime() const
45 | {
46 | return mTime;
47 | }
48 |
49 | void radioVector::setTime(const GSM::Time& wTime)
50 | {
51 | mTime = wTime;
52 | }
53 |
54 | bool radioVector::operator>(const radioVector& other) const
55 | {
56 | return mTime > other.mTime;
57 | }
58 |
59 | signalVector *radioVector::getVector(size_t chan) const
60 | {
61 | if (chan >= vectors.size())
62 | return NULL;
63 |
64 | return vectors[chan];
65 | }
66 |
67 | bool radioVector::setVector(signalVector *vector, size_t chan)
68 | {
69 | if (chan >= vectors.size())
70 | return false;
71 |
72 | vectors[chan] = vector;
73 |
74 | return true;
75 | }
76 |
77 | noiseVector::noiseVector(size_t size)
78 | : std::vector(size), itr(0)
79 | {
80 | }
81 |
82 | float noiseVector::avg() const
83 | {
84 | float val = 0.0;
85 |
86 | for (size_t i = 0; i < size(); i++)
87 | val += (*this)[i];
88 |
89 | return val / (float) size();
90 | }
91 |
92 | bool noiseVector::insert(float val)
93 | {
94 | if (!size())
95 | return false;
96 |
97 | if (itr >= this->size())
98 | itr = 0;
99 |
100 | (*this)[itr++] = val;
101 |
102 | return true;
103 | }
104 |
105 | GSM::Time VectorQueue::nextTime() const
106 | {
107 | GSM::Time retVal;
108 | mLock.lock();
109 |
110 | while (mQ.size()==0)
111 | mWriteSignal.wait(mLock);
112 |
113 | retVal = mQ.top()->getTime();
114 | mLock.unlock();
115 |
116 | return retVal;
117 | }
118 |
119 | radioVector* VectorQueue::getStaleBurst(const GSM::Time& targTime)
120 | {
121 | mLock.lock();
122 | if ((mQ.size()==0)) {
123 | mLock.unlock();
124 | return NULL;
125 | }
126 |
127 | if (mQ.top()->getTime() < targTime) {
128 | radioVector* retVal = mQ.top();
129 | mQ.pop();
130 | mLock.unlock();
131 | return retVal;
132 | }
133 | mLock.unlock();
134 |
135 | return NULL;
136 | }
137 |
138 | radioVector* VectorQueue::getCurrentBurst(const GSM::Time& targTime)
139 | {
140 | mLock.lock();
141 | if ((mQ.size()==0)) {
142 | mLock.unlock();
143 | return NULL;
144 | }
145 |
146 | if (mQ.top()->getTime() == targTime) {
147 | radioVector* retVal = mQ.top();
148 | mQ.pop();
149 | mLock.unlock();
150 | return retVal;
151 | }
152 | mLock.unlock();
153 |
154 | return NULL;
155 | }
156 |
--------------------------------------------------------------------------------
/Transceiver52M/radioVector.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Written by Thomas Tsou
3 | * Based on code by Harvind S Samra
4 | *
5 | * Copyright 2011 Free Software Foundation, Inc.
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Affero General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Affero General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Affero General Public License
18 | * along with this program. If not, see .
19 | * See the COPYING file in the main directory for details.
20 | */
21 |
22 | #ifndef RADIOVECTOR_H
23 | #define RADIOVECTOR_H
24 |
25 | #include "sigProcLib.h"
26 | #include "GSMCommon.h"
27 | #include "Interthread.h"
28 |
29 | class radioVector {
30 | public:
31 | radioVector(GSM::Time& wTime, size_t size = 0,
32 | size_t start = 0, size_t chans = 1);
33 |
34 | radioVector(GSM::Time& wTime, signalVector *vector);
35 | ~radioVector();
36 |
37 | GSM::Time getTime() const;
38 | void setTime(const GSM::Time& wTime);
39 | bool operator>(const radioVector& other) const;
40 |
41 | signalVector *getVector(size_t chan = 0) const;
42 | bool setVector(signalVector *vector, size_t chan = 0);
43 | size_t chans() const { return vectors.size(); }
44 | private:
45 | std::vector vectors;
46 | GSM::Time mTime;
47 | };
48 |
49 | class noiseVector : std::vector {
50 | public:
51 | noiseVector(size_t size = 0);
52 | bool insert(float val);
53 | float avg() const;
54 |
55 | private:
56 | size_t itr;
57 | };
58 |
59 | class VectorFIFO : public InterthreadQueue { };
60 |
61 | class VectorQueue : public InterthreadPriorityQueue {
62 | public:
63 | GSM::Time nextTime() const;
64 | radioVector* getStaleBurst(const GSM::Time& targTime);
65 | radioVector* getCurrentBurst(const GSM::Time& targTime);
66 | };
67 |
68 | #endif /* RADIOVECTOR_H */
69 |
--------------------------------------------------------------------------------
/Transceiver52M/sigProcLib.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | * This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
5 | *
6 | * This use of this software may be subject to additional restrictions.
7 | * See the LEGAL file in the main directory for details.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 |
13 | */
14 |
15 | #ifndef SIGPROCLIB_H
16 | #define SIGPROCLIB_H
17 |
18 | #include "Vector.h"
19 | #include "Complex.h"
20 | #include "BitVector.h"
21 | #include "signalVector.h"
22 |
23 | /* Burst lengths */
24 | #define NORMAL_BURST_NBITS 148
25 | #define EDGE_BURST_NBITS 444
26 | #define EDGE_BURST_NSYMS (EDGE_BURST_NBITS / 3)
27 |
28 | /** Codes for burst types of received bursts*/
29 | enum CorrType{
30 | OFF, ///< timeslot is off
31 | TSC, ///< timeslot should contain a normal burst
32 | EXT_RACH, ///< timeslot should contain an extended access burst
33 | RACH, ///< timeslot should contain an access burst
34 | EDGE, ///< timeslot should contain an EDGE burst
35 | IDLE ///< timeslot is an idle (or dummy) burst
36 | };
37 |
38 | enum SignalError {
39 | SIGERR_NONE,
40 | SIGERR_BOUNDS,
41 | SIGERR_CLIP,
42 | SIGERR_UNSUPPORTED,
43 | SIGERR_INTERNAL,
44 | };
45 |
46 | /*
47 | * Burst detection threshold
48 | *
49 | * Decision threshold value for burst gating on peak-to-average value of
50 | * correlated synchronization sequences. Lower values pass more bursts up
51 | * to upper layers but will increase the false detection rate.
52 | */
53 | #define BURST_THRESH 4.0
54 |
55 | /** Setup the signal processing library */
56 | bool sigProcLibSetup();
57 |
58 | /** Destroy the signal processing library */
59 | void sigProcLibDestroy(void);
60 |
61 | /** Operate soft slicer on a soft-bit vector */
62 | bool vectorSlicer(SoftVector *x);
63 |
64 | /** GMSK modulate a GSM burst of bits */
65 | signalVector *modulateBurst(const BitVector &wBurst,
66 | int guardPeriodLength,
67 | int sps, bool emptyPulse = false);
68 |
69 | /** 8-PSK modulate a burst of bits */
70 | signalVector *modulateEdgeBurst(const BitVector &bits,
71 | int sps, bool emptyPulse = false);
72 |
73 | /** Generate a EDGE burst with random payload - 4 SPS (625 samples) only */
74 | signalVector *generateEdgeBurst(int tsc);
75 |
76 | /** Generate an empty burst - 4 or 1 SPS */
77 | signalVector *generateEmptyBurst(int sps, int tn);
78 |
79 | /** Generate a normal GSM burst with random payload - 4 or 1 SPS */
80 | signalVector *genRandNormalBurst(int tsc, int sps, int tn);
81 |
82 | /** Generate an access GSM burst with random payload - 4 or 1 SPS */
83 | signalVector *genRandAccessBurst(int delay, int sps, int tn);
84 |
85 | /** Generate a dummy GSM burst - 4 or 1 SPS */
86 | signalVector *generateDummyBurst(int sps, int tn);
87 |
88 | /**
89 | Apply a scalar to a vector.
90 | @param x The vector of interest.
91 | @param scale The scalar.
92 | */
93 | void scaleVector(signalVector &x,
94 | complex scale);
95 |
96 | /**
97 | Rough energy estimator.
98 | @param rxBurst A GSM burst.
99 | @param windowLength The number of burst samples used to compute burst energy
100 | @return The average power of the received burst.
101 | */
102 | float energyDetect(const signalVector &rxBurst,
103 | unsigned windowLength);
104 | /**
105 | 8-PSK/GMSK/RACH burst detector
106 | @param burst The received GSM burst of interest
107 | @param tsc Midamble type (0..7) also known as TSC
108 | @param threshold The threshold that the received burst's post-correlator SNR is compared against to determine validity.
109 | @param sps The number of samples per GSM symbol.
110 | @param amplitude The estimated amplitude of received TSC burst.
111 | @param toa The estimate time-of-arrival of received TSC burst (in symbols).
112 | @param max_toa The maximum expected time-of-arrival (in symbols).
113 | @return positive value (CorrType) if threshold value is reached,
114 | negative value (-SignalError) on error,
115 | zero (SIGERR_NONE) if no burst is detected
116 | */
117 | int detectAnyBurst(const signalVector &burst,
118 | unsigned tsc,
119 | float threshold,
120 | int sps,
121 | CorrType type,
122 | complex &,
123 | float &toa,
124 | unsigned max_toa);
125 |
126 | /** Demodulate burst basde on type and output soft bits */
127 | SoftVector *demodAnyBurst(const signalVector &burst, int sps,
128 | complex amp, float toa, CorrType type);
129 |
130 | #endif /* SIGPROCLIB_H */
131 |
--------------------------------------------------------------------------------
/Transceiver52M/signalVector.cpp:
--------------------------------------------------------------------------------
1 | #include "signalVector.h"
2 |
3 | signalVector::signalVector(size_t size, vector_alloc_func wAllocFunc, vector_free_func wFreeFunc)
4 | : Vector(size, wAllocFunc, wFreeFunc),
5 | real(false), aligned(false), symmetry(NONE)
6 | {
7 | }
8 |
9 | signalVector::signalVector(size_t size, size_t start, vector_alloc_func wAllocFunc, vector_free_func wFreeFunc)
10 | : Vector(size + start, wAllocFunc, wFreeFunc),
11 | real(false), aligned(false), symmetry(NONE)
12 | {
13 | mStart = mData + start;
14 | }
15 |
16 | signalVector::signalVector(complex *data, size_t start, size_t span, vector_alloc_func wAllocFunc, vector_free_func wFreeFunc)
17 | : Vector(data, data + start, data + start + span, wAllocFunc, wFreeFunc),
18 | real(false), aligned(false), symmetry(NONE)
19 | {
20 | }
21 |
22 | signalVector::signalVector(const signalVector &vector)
23 | : Vector(vector.size() + vector.getStart()), aligned(false)
24 | {
25 | mStart = mData + vector.getStart();
26 | vector.copyTo(*this);
27 | symmetry = vector.getSymmetry();
28 | real = vector.isReal();
29 | };
30 |
31 | signalVector::signalVector(const signalVector &vector,
32 | size_t start, size_t tail)
33 | : Vector(start + vector.size() + tail), aligned(false)
34 | {
35 | mStart = mData + start;
36 | vector.copyTo(*this);
37 | symmetry = vector.getSymmetry();
38 | real = vector.isReal();
39 | };
40 |
41 | void signalVector::operator=(const signalVector& vector)
42 | {
43 | resize(vector.size() + vector.getStart());
44 |
45 | unsigned int i;
46 | complex *dst = mData;
47 | complex *src = vector.mData;
48 | for (i = 0; i < size(); i++, src++, dst++)
49 | *dst = *src;
50 | /* TODO: optimize for non non-trivially copyable types: */
51 | /*memcpy(mData, vector.mData, bytes()); */
52 | mStart = mData + vector.getStart();
53 | }
54 |
55 | signalVector signalVector::segment(size_t start, size_t span)
56 | {
57 | return signalVector(mData, start, span);
58 | }
59 |
60 | size_t signalVector::getStart() const
61 | {
62 | return mStart - mData;
63 | }
64 |
65 | size_t signalVector::updateHistory()
66 | {
67 | size_t num = getStart();
68 | unsigned int i;
69 | complex *dst = mData;
70 | complex *src = mStart + this->size() - num;
71 | for (i = 0; i < num; i++, src++, dst++)
72 | *dst = *src;
73 | /* TODO: optimize for non non-trivially copyable types: */
74 | /*memmove(mData, mStart + this->size() - num, num * sizeof(complex)); */
75 |
76 | return num;
77 | }
78 |
79 | Symmetry signalVector::getSymmetry() const
80 | {
81 | return symmetry;
82 | }
83 |
84 | void signalVector::setSymmetry(Symmetry symmetry)
85 | {
86 | this->symmetry = symmetry;
87 | }
88 |
89 | bool signalVector::isReal() const
90 | {
91 | return real;
92 | }
93 |
94 | void signalVector::isReal(bool wOnly)
95 | {
96 | real = wOnly;
97 | }
98 |
99 | bool signalVector::isAligned() const
100 | {
101 | return aligned;
102 | }
103 |
104 | void signalVector::setAligned(bool aligned)
105 | {
106 | this->aligned = aligned;
107 | }
108 |
--------------------------------------------------------------------------------
/Transceiver52M/signalVector.h:
--------------------------------------------------------------------------------
1 | #ifndef _SIGNALVECTOR_H_
2 | #define _SIGNALVECTOR_H_
3 |
4 | #include
5 | #include
6 |
7 | /** Vector symmetry */
8 | enum Symmetry {
9 | NONE = 0,
10 | ABSSYM = 1
11 | };
12 |
13 | class signalVector: public Vector {
14 | public:
15 | /** Default constructor */
16 | signalVector(size_t size = 0, vector_alloc_func wAllocFunc = NULL, vector_free_func wFreeFunc = NULL);
17 |
18 | /** Construct with head room */
19 | signalVector(size_t size, size_t start, vector_alloc_func wAllocFunc = NULL, vector_free_func wFreeFunc = NULL);
20 |
21 | /** Construct from existing buffer data (buffer not managed) */
22 | signalVector(complex *data, size_t start, size_t span, vector_alloc_func wAllocFunc = NULL, vector_free_func wFreeFunc = NULL);
23 |
24 | /** Construct by from existing vector */
25 | signalVector(const signalVector &vector);
26 |
27 | /** Construct by from existing vector and append head-tail room */
28 | signalVector(const signalVector &vector, size_t start, size_t tail = 0);
29 |
30 | /** Override base assignment operator to include start offsets */
31 | void operator=(const signalVector& vector);
32 |
33 | /** Return an alias to a segment of this signalVector. */
34 | signalVector segment(size_t start, size_t span);
35 |
36 | /** Return head room */
37 | size_t getStart() const;
38 | size_t updateHistory();
39 |
40 | Symmetry getSymmetry() const;
41 | void setSymmetry(Symmetry symmetry);
42 |
43 | bool isReal() const;
44 | void isReal(bool real);
45 |
46 | bool isAligned() const;
47 | void setAligned(bool aligned);
48 |
49 | private:
50 | bool real;
51 | bool aligned;
52 | Symmetry symmetry;
53 | };
54 |
55 | #endif /* _SIGNALVECTOR_H_ */
56 |
--------------------------------------------------------------------------------
/Transceiver52M/std_inband.rbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttsou/osmo-trx/5e6f3e0cadf7859ae90073cd07afec550892a448/Transceiver52M/std_inband.rbf
--------------------------------------------------------------------------------
/config/ax_check_compile_flag.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Check whether the given FLAG works with the current language's compiler
12 | # or gives an error. (Warnings, however, are ignored)
13 | #
14 | # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
15 | # success/failure.
16 | #
17 | # If EXTRA-FLAGS is defined, it is added to the current language's default
18 | # flags (e.g. CFLAGS) when the check is done. The check is thus made with
19 | # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
20 | # force the compiler to issue an error when a bad flag is given.
21 | #
22 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
23 | # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
24 | #
25 | # LICENSE
26 | #
27 | # Copyright (c) 2008 Guido U. Draheim
28 | # Copyright (c) 2011 Maarten Bosmans
29 | #
30 | # This program is free software: you can redistribute it and/or modify it
31 | # under the terms of the GNU General Public License as published by the
32 | # Free Software Foundation, either version 3 of the License, or (at your
33 | # option) any later version.
34 | #
35 | # This program is distributed in the hope that it will be useful, but
36 | # WITHOUT ANY WARRANTY; without even the implied warranty of
37 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
38 | # Public License for more details.
39 | #
40 | # You should have received a copy of the GNU General Public License along
41 | # with this program. If not, see .
42 | #
43 | # As a special exception, the respective Autoconf Macro's copyright owner
44 | # gives unlimited permission to copy, distribute and modify the configure
45 | # scripts that are the output of Autoconf when processing the Macro. You
46 | # need not follow the terms of the GNU General Public License when using
47 | # or distributing such scripts, even though portions of the text of the
48 | # Macro appear in them. The GNU General Public License (GPL) does govern
49 | # all other use of the material that constitutes the Autoconf Macro.
50 | #
51 | # This special exception to the GPL applies to versions of the Autoconf
52 | # Macro released by the Autoconf Archive. When you make and distribute a
53 | # modified version of the Autoconf Macro, you may extend this special
54 | # exception to the GPL to apply to your modified version as well.
55 |
56 | #serial 2
57 |
58 | AC_DEFUN([AX_CHECK_COMPILE_FLAG],
59 | [AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
60 | AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
61 | AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
62 | ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
63 | _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
64 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
65 | [AS_VAR_SET(CACHEVAR,[yes])],
66 | [AS_VAR_SET(CACHEVAR,[no])])
67 | _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
68 | AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
69 | [m4_default([$2], :)],
70 | [m4_default([$3], :)])
71 | AS_VAR_POPDEF([CACHEVAR])dnl
72 | ])dnl AX_CHECK_COMPILE_FLAGS
73 |
--------------------------------------------------------------------------------
/config/ax_cxx_compile_stdcxx_11.m4:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
3 | # =============================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Check for baseline language coverage in the compiler for the C++11
12 | # standard; if necessary, add switches to CXX and CXXCPP to enable
13 | # support.
14 | #
15 | # This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX
16 | # macro with the version set to C++11. The two optional arguments are
17 | # forwarded literally as the second and third argument respectively.
18 | # Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for
19 | # more information. If you want to use this macro, you also need to
20 | # download the ax_cxx_compile_stdcxx.m4 file.
21 | #
22 | # LICENSE
23 | #
24 | # Copyright (c) 2008 Benjamin Kosnik
25 | # Copyright (c) 2012 Zack Weinberg
26 | # Copyright (c) 2013 Roy Stogner
27 | # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov
28 | # Copyright (c) 2015 Paul Norman
29 | # Copyright (c) 2015 Moritz Klammler
30 | #
31 | # Copying and distribution of this file, with or without modification, are
32 | # permitted in any medium without royalty provided the copyright notice
33 | # and this notice are preserved. This file is offered as-is, without any
34 | # warranty.
35 |
36 | #serial 18
37 |
38 | AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])
39 | AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])])
40 |
--------------------------------------------------------------------------------
/config/ax_sse.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_ext.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_SSE
8 | #
9 | # DESCRIPTION
10 | #
11 | # Find SIMD extensions supported by compiler. The -m"simdextensionname" is
12 | # added to SIMD_FLAGS if compiler supports it. For example, if "sse2" is
13 | # available, then "-msse2" is added to SIMD_FLAGS.
14 | #
15 | # This macro calls:
16 | #
17 | # AC_SUBST(SIMD_FLAGS)
18 | #
19 | # And defines:
20 | #
21 | # HAVE_SSE3 / HAVE_SSE4.1
22 | #
23 | # LICENSE
24 | #
25 | # Copyright (c) 2007 Christophe Tournayre
26 | # Copyright (c) 2013 Michael Petch
27 | #
28 | # Copying and distribution of this file, with or without modification, are
29 | # permitted in any medium without royalty provided the copyright notice
30 | # and this notice are preserved. This file is offered as-is, without any
31 | # warranty.
32 | #
33 | # NOTE: The functionality that requests the cpuid has been stripped because
34 | # this project detects the CPU capabilities during runtime. However, we
35 | # still need to check if the compiler supports the requested SIMD flag
36 |
37 | #serial 12
38 |
39 | AC_DEFUN([AX_SSE],
40 | [
41 | AC_REQUIRE([AC_CANONICAL_HOST])
42 |
43 | AM_CONDITIONAL(HAVE_SSE3, false)
44 | AM_CONDITIONAL(HAVE_SSE4_1, false)
45 |
46 | case $host_cpu in
47 | i[[3456]]86*|x86_64*|amd64*)
48 | AX_CHECK_COMPILE_FLAG(-msse3, ax_cv_support_sse3_ext=yes, [])
49 | if test x"$ax_cv_support_sse3_ext" = x"yes"; then
50 | SIMD_FLAGS="$SIMD_FLAGS -msse3"
51 | AC_DEFINE(HAVE_SSE3,,
52 | [Support SSE3 (Streaming SIMD Extensions 3) instructions])
53 | AM_CONDITIONAL(HAVE_SSE3, true)
54 | else
55 | AC_MSG_WARN([Your compiler does not support SSE3 instructions])
56 | fi
57 |
58 | AX_CHECK_COMPILE_FLAG(-msse4.1, ax_cv_support_sse41_ext=yes, [])
59 | if test x"$ax_cv_support_sse41_ext" = x"yes"; then
60 | SIMD_FLAGS="$SIMD_FLAGS -msse4.1"
61 | AC_DEFINE(HAVE_SSE4_1,,
62 | [Support SSE4.1 (Streaming SIMD Extensions 4.1) instructions])
63 | AM_CONDITIONAL(HAVE_SSE4_1, true)
64 | else
65 | AC_MSG_WARN([Your compiler does not support SSE4.1])
66 | fi
67 | ;;
68 | esac
69 |
70 | AC_SUBST(SIMD_FLAGS)
71 | ])
72 |
--------------------------------------------------------------------------------
/contrib/Makefile.am:
--------------------------------------------------------------------------------
1 | SUBDIRS = systemd
2 |
--------------------------------------------------------------------------------
/contrib/jenkins.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # jenkins build helper script for osmo-trx. This is how we build on jenkins.osmocom.org
3 | #
4 | # environment variables:
5 | # * INSTR: configure the CPU instruction set ("--with-sse", "--with-neon" or "--with-neon-vfpv4")
6 | # * WITH_MANUALS: build manual PDFs if set to "1"
7 | # * PUBLISH: upload manuals after building if set to "1" (ignored without WITH_MANUALS = "1")
8 | # * INSIDE_CHROOT: (used internally) set to "1" when the script runs with QEMU in an ARM chroot
9 | #
10 | set -ex
11 |
12 | substr() { [ -z "${2##*$1*}" ]; }
13 |
14 | #apt-get install qemu qemu-user-static qemu-system-arm debootstrap fakeroot proot
15 | mychroot_nocwd() {
16 | # LC_ALL + LANGUAGE set to avoid lots of print errors due to locale not being set inside container
17 | # PATH is needed to be able to reach binaries like ldconfig without logging in to root, which adds the paths to PATH.
18 | # PROOT_NO_SECCOMP is requried due to proot bug #106
19 | LC_ALL=C LANGUAGE=C PATH="$PATH:/usr/sbin:/sbin" PROOT_NO_SECCOMP=1 proot -r "$ROOTFS" -w / -b /proc --root-id -q qemu-arm-static "$@"
20 | }
21 |
22 | mychroot() {
23 | mychroot_nocwd -w / "$@"
24 | }
25 |
26 | base="$PWD"
27 | deps="$base/deps"
28 | inst="$deps/install"
29 | export deps inst
30 |
31 | if [ -z "${INSIDE_CHROOT}" ]; then
32 |
33 | osmo-clean-workspace.sh
34 |
35 | # Only use ARM chroot if host is not ARM and the target is ARM:
36 | if ! $(substr "arm" "$(uname -m)") && [ "x${INSTR}" = "x--with-neon" -o "x${INSTR}" = "x--with-neon-vfpv4" ]; then
37 |
38 | OSMOTRX_DIR="$PWD" # we assume we are called as contrib/jenkins.sh
39 | ROOTFS_PREFIX="${ROOTFS_PREFIX:-$HOME}"
40 | ROOTFS="${ROOTFS_PREFIX}/qemu-img"
41 | mkdir -p "${ROOTFS_PREFIX}"
42 |
43 | # Prepare chroot:
44 | if [ ! -d "$ROOTFS" ]; then
45 | mkdir -p "$ROOTFS"
46 | if [ "x${USE_DEBOOTSTRAP}" = "x1" ]; then
47 | fakeroot qemu-debootstrap --foreign --include="linux-image-armmp-lpae" --arch=armhf stretch "$ROOTFS" http://ftp.de.debian.org/debian/
48 | # Hack to avoid debootstrap trying to mount /proc, as it will fail with "no permissions" and anyway proot takes care of it:
49 | sed -i "s/setup_proc//g" "$ROOTFS/debootstrap/suite-script"
50 | mychroot /debootstrap/debootstrap --second-stage --verbose http://ftp.de.debian.org/debian/
51 | else
52 | YESTERDAY=$(python -c 'import datetime ; print((datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y%m%d"))')
53 | wget -nc -q "https://uk.images.linuxcontainers.org/images/debian/stretch/armhf/default/${YESTERDAY}_22:42/rootfs.tar.xz"
54 | tar -xf rootfs.tar.xz -C "$ROOTFS/" || true
55 | echo "nameserver 8.8.8.8" > "$ROOTFS/etc/resolv.conf"
56 | fi
57 | mychroot -b /dev apt-get update
58 | mychroot apt-get -y install build-essential dh-autoreconf pkg-config libuhd-dev libusb-1.0-0-dev libusb-dev git libtalloc-dev libgnutls28-dev stow
59 | fi
60 | # Run jenkins.sh inside the chroot:
61 | INSIDE_CHROOT=1 mychroot_nocwd \
62 | -w /osmo-trx \
63 | -b "$OSMOTRX_DIR:/osmo-trx" \
64 | -b "$(which osmo-clean-workspace.sh):/usr/bin/osmo-clean-workspace.sh" \
65 | -b "$(which osmo-build-dep.sh):/usr/bin/osmo-build-dep.sh" \
66 | -b "$(which osmo-deps.sh):/usr/bin/osmo-deps.sh" \
67 | ./contrib/jenkins.sh
68 | exit 0
69 | fi
70 | fi
71 |
72 | mkdir "$deps" || true
73 |
74 | osmo-build-dep.sh libosmocore "" "--enable-sanitize --disable-doxygen --disable-pcsc"
75 | osmo-build-dep.sh libusrp
76 |
77 | export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
78 | export LD_LIBRARY_PATH="$inst/lib"
79 | export PATH="$inst/bin:$PATH"
80 |
81 | CONFIG="--enable-sanitize --enable-werror --with-uhd --with-usrp1 --with-lms $INSTR"
82 |
83 | # Additional configure options and depends
84 | if [ "$WITH_MANUALS" = "1" ]; then
85 | osmo-build-dep.sh osmo-gsm-manuals
86 | CONFIG="$CONFIG --enable-manuals"
87 | fi
88 |
89 | set +x
90 | echo
91 | echo
92 | echo
93 | echo " =============================== osmo-trx ==============================="
94 | echo
95 | set -x
96 |
97 | cd "$base"
98 | autoreconf --install --force
99 | ./configure $CONFIG
100 | $MAKE $PARALLEL_MAKE
101 | $MAKE check \
102 | || cat-testlogs.sh
103 | DISTCHECK_CONFIGURE_FLAGS="$CONFIG" $MAKE distcheck \
104 | || cat-testlogs.sh
105 |
106 | if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
107 | make -C "$base/doc/manuals" publish
108 | fi
109 |
110 | osmo-clean-workspace.sh
111 |
--------------------------------------------------------------------------------
/contrib/systemd/Makefile.am:
--------------------------------------------------------------------------------
1 | EXTRA_DIST = \
2 | osmo-trx-lms.service \
3 | osmo-trx-uhd.service \
4 | osmo-trx-usrp1.service
5 |
6 | if HAVE_SYSTEMD
7 | SYSTEMD_SERVICES =
8 |
9 | if DEVICE_UHD
10 | SYSTEMD_SERVICES += osmo-trx-uhd.service
11 | endif
12 |
13 | if DEVICE_USRP1
14 | SYSTEMD_SERVICES += osmo-trx-usrp1.service
15 | endif
16 |
17 | if DEVICE_LMS
18 | SYSTEMD_SERVICES += osmo-trx-lms.service
19 | endif
20 |
21 | systemdsystemunit_DATA = $(SYSTEMD_SERVICES)
22 | endif # HAVE_SYSTEMD
23 |
--------------------------------------------------------------------------------
/contrib/systemd/osmo-trx-lms.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Osmocom SDR BTS L1 Transceiver (LimeSuite backend)
3 |
4 | [Service]
5 | Type=simple
6 | Restart=always
7 | ExecStart=/usr/bin/osmo-trx-lms -C /etc/osmocom/osmo-trx-lms.cfg
8 | RestartSec=2
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/contrib/systemd/osmo-trx-uhd.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Osmocom SDR BTS L1 Transceiver (UHD Backend)
3 |
4 | [Service]
5 | Type=simple
6 | Restart=always
7 | ExecStart=/usr/bin/osmo-trx-uhd -C /etc/osmocom/osmo-trx-uhd.cfg
8 | RestartSec=2
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/contrib/systemd/osmo-trx-usrp1.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Osmocom SDR BTS L1 Transceiver (libusrp backend)
3 |
4 | [Service]
5 | Type=simple
6 | Restart=always
7 | ExecStart=/usr/bin/osmo-trx-usrp1 -C /etc/osmocom/osmo-trx-usrp1.cfg
8 | RestartSec=2
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/debian/compat:
--------------------------------------------------------------------------------
1 | 9
2 |
--------------------------------------------------------------------------------
/debian/control:
--------------------------------------------------------------------------------
1 | Source: osmo-trx
2 | Section: net
3 | Priority: optional
4 | Maintainer: Ivan Klyuchnikov
5 | Build-Depends: debhelper (>= 9),
6 | autotools-dev,
7 | autoconf-archive,
8 | pkg-config,
9 | dh-autoreconf,
10 | libuhd-dev,
11 | libusb-1.0-0-dev,
12 | libboost-all-dev,
13 | libfftw3-dev,
14 | libtalloc-dev,
15 | libusrp-dev,
16 | liblimesuite-dev,
17 | libosmocore-dev (>= 0.10.0)
18 | Standards-Version: 3.9.6
19 | Vcs-Browser: http://cgit.osmocom.org/osmo-trx
20 | Vcs-Git: git://git.osmocom.org/osmo-trx
21 | Homepage: https://projects.osmocom.org/projects/osmotrx
22 |
23 | Package: osmo-trx
24 | Depends: osmo-trx-uhd
25 | Architecture: all
26 | Description: Metapackage for osmo-trx-uhd
27 |
28 | Package: osmo-trx-dbg
29 | Architecture: any
30 | Section: debug
31 | Priority: extra
32 | Depends: osmo-trx-uhd (= ${binary:Version}), osmo-trx-usrp1 (= ${binary:Version}), osmo-trx-lms (= ${binary:Version}), ${misc:Depends}
33 | Description: Debug symbols for the osmo-trx-*
34 | Make debugging possible
35 |
36 | Package: osmo-trx-uhd
37 | Architecture: any
38 | Depends: ${shlibs:Depends}, ${misc:Depends}
39 | Description: SDR transceiver that implements Layer 1 of a GSM BTS (UHD)
40 | OsmoTRX is a software-defined radio transceiver that implements the Layer 1
41 | physical layer of a BTS comprising the following 3GPP specifications:
42 | .
43 | TS 05.01 "Physical layer on the radio path"
44 | TS 05.02 "Multiplexing and Multiple Access on the Radio Path"
45 | TS 05.04 "Modulation"
46 | TS 05.10 "Radio subsystem synchronization"
47 | .
48 | In this context, BTS is "Base transceiver station". It's the stations that
49 | connect mobile phones to the mobile network.
50 | .
51 | 3GPP is the "3rd Generation Partnership Project" which is the collaboration
52 | between different telecommunication associations for developing new
53 | generations of mobile phone networks. (post-2G/GSM)
54 |
55 | Package: osmo-trx-usrp1
56 | Architecture: any
57 | Depends: ${shlibs:Depends}, ${misc:Depends}
58 | Description: SDR transceiver that implements Layer 1 of a GSM BTS (USRP1)
59 | OsmoTRX is a software-defined radio transceiver that implements the Layer 1
60 | physical layer of a BTS comprising the following 3GPP specifications:
61 | .
62 | TS 05.01 "Physical layer on the radio path"
63 | TS 05.02 "Multiplexing and Multiple Access on the Radio Path"
64 | TS 05.04 "Modulation"
65 | TS 05.10 "Radio subsystem synchronization"
66 | .
67 | In this context, BTS is "Base transceiver station". It's the stations that
68 | connect mobile phones to the mobile network.
69 | .
70 | 3GPP is the "3rd Generation Partnership Project" which is the collaboration
71 | between different telecommunication associations for developing new
72 | generations of mobile phone networks. (post-2G/GSM)
73 |
74 | Package: osmo-trx-lms
75 | Architecture: any
76 | Depends: ${shlibs:Depends}, ${misc:Depends}
77 | Description: SDR transceiver that implements Layer 1 of a GSM BTS (LimeSuite)
78 | OsmoTRX is a software-defined radio transceiver that implements the Layer 1
79 | physical layer of a BTS comprising the following 3GPP specifications:
80 | .
81 | TS 05.01 "Physical layer on the radio path"
82 | TS 05.02 "Multiplexing and Multiple Access on the Radio Path"
83 | TS 05.04 "Modulation"
84 | TS 05.10 "Radio subsystem synchronization"
85 | .
86 | In this context, BTS is "Base transceiver station". It's the stations that
87 | connect mobile phones to the mobile network.
88 | .
89 | 3GPP is the "3rd Generation Partnership Project" which is the collaboration
90 | between different telecommunication associations for developing new
91 | generations of mobile phone networks. (post-2G/GSM)
92 |
--------------------------------------------------------------------------------
/debian/osmo-trx-lms.install:
--------------------------------------------------------------------------------
1 | etc/osmocom/osmo-trx-lms.cfg
2 | lib/systemd/system/osmo-trx-lms.service
3 | /usr/bin/osmo-trx-lms
4 | /usr/share/doc/osmo-trx/examples/osmo-trx-lms/osmo-trx-limesdr.cfg /usr/share/doc/osmo-trx/examples/osmo-trx-lms/
5 |
--------------------------------------------------------------------------------
/debian/osmo-trx-uhd.install:
--------------------------------------------------------------------------------
1 | etc/osmocom/osmo-trx-uhd.cfg
2 | lib/systemd/system/osmo-trx-uhd.service
3 | /usr/bin/osmo-trx-uhd
4 | /usr/share/doc/osmo-trx/examples/osmo-trx-uhd/osmo-trx-usrp_b200.cfg /usr/share/doc/osmo-trx/examples/osmo-trx-uhd/
5 | /usr/share/doc/osmo-trx/examples/osmo-trx-uhd/osmo-trx-limesdr.cfg /usr/share/doc/osmo-trx/examples/osmo-trx-uhd/
6 | /usr/share/doc/osmo-trx/examples/osmo-trx-uhd/osmo-trx-umtrx.cfg /usr/share/doc/osmo-trx/examples/osmo-trx-uhd/
7 |
--------------------------------------------------------------------------------
/debian/osmo-trx-usrp1.install:
--------------------------------------------------------------------------------
1 | lib/systemd/system/osmo-trx-usrp1.service
2 | /usr/bin/osmo-trx-usrp1
3 | /usr/share/usrp/rev2/std_inband.rbf
4 | /usr/share/usrp/rev4/std_inband.rbf
5 |
--------------------------------------------------------------------------------
/debian/osmo-trx.install:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttsou/osmo-trx/5e6f3e0cadf7859ae90073cd07afec550892a448/debian/osmo-trx.install
--------------------------------------------------------------------------------
/debian/patches/build-for-debian8.patch:
--------------------------------------------------------------------------------
1 | Index: osmo-trx/debian/control
2 | ===================================================================
3 | --- osmo-trx.orig/debian/control
4 | +++ osmo-trx/debian/control
5 | @@ -13,7 +13,6 @@ Build-Depends: debhelper (>= 9),
6 | libfftw3-dev,
7 | libtalloc-dev,
8 | libusrp-dev,
9 | - liblimesuite-dev,
10 | libosmocore-dev (>= 0.10.0)
11 | Standards-Version: 3.9.6
12 | Vcs-Browser: http://cgit.osmocom.org/osmo-trx
13 | @@ -29,7 +28,7 @@ Package: osmo-trx-dbg
14 | Architecture: any
15 | Section: debug
16 | Priority: extra
17 | -Depends: osmo-trx-uhd (= ${binary:Version}), osmo-trx-usrp1 (= ${binary:Version}), osmo-trx-lms (= ${binary:Version}), ${misc:Depends}
18 | +Depends: osmo-trx-uhd (= ${binary:Version}), osmo-trx-usrp1 (= ${binary:Version}), ${misc:Depends}
19 | Description: Debug symbols for the osmo-trx-*
20 | Make debugging possible
21 |
22 | @@ -70,22 +70,3 @@ Description: SDR transceiver that implem
23 | 3GPP is the "3rd Generation Partnership Project" which is the collaboration
24 | between different telecommunication associations for developing new
25 | generations of mobile phone networks. (post-2G/GSM)
26 | -
27 | -Package: osmo-trx-lms
28 | -Architecture: any
29 | -Depends: ${shlibs:Depends}, ${misc:Depends}
30 | -Description: SDR transceiver that implements Layer 1 of a GSM BTS (LimeSuite)
31 | - OsmoTRX is a software-defined radio transceiver that implements the Layer 1
32 | - physical layer of a BTS comprising the following 3GPP specifications:
33 | - .
34 | - TS 05.01 "Physical layer on the radio path"
35 | - TS 05.02 "Multiplexing and Multiple Access on the Radio Path"
36 | - TS 05.04 "Modulation"
37 | - TS 05.10 "Radio subsystem synchronization"
38 | - .
39 | - In this context, BTS is "Base transceiver station". It's the stations that
40 | - connect mobile phones to the mobile network.
41 | - .
42 | - 3GPP is the "3rd Generation Partnership Project" which is the collaboration
43 | - between different telecommunication associations for developing new
44 | - generations of mobile phone networks. (post-2G/GSM)
45 | Index: osmo-trx/debian/rules
46 | ===================================================================
47 | --- osmo-trx.orig/debian/rules
48 | +++ osmo-trx/debian/rules
49 | @@ -9,7 +9,7 @@ override_dh_shlibdeps:
50 | dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
51 |
52 | override_dh_auto_configure:
53 | - dh_auto_configure -- --with-uhd --with-usrp1 --with-lms --with-systemdsystemunitdir=/lib/systemd/system
54 | + dh_auto_configure -- --with-uhd --with-usrp1 --with-systemdsystemunitdir=/lib/systemd/system
55 |
56 | override_dh_strip:
57 | dh_strip --dbg-package=osmo-trx-dbg
58 |
--------------------------------------------------------------------------------
/debian/patches/series:
--------------------------------------------------------------------------------
1 | # build-for-debian8.patch
2 |
--------------------------------------------------------------------------------
/debian/rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 |
3 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all
4 |
5 | %:
6 | dh $@ --with autoreconf
7 |
8 | override_dh_shlibdeps:
9 | dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
10 |
11 | override_dh_auto_configure:
12 | dh_auto_configure -- --with-uhd --with-usrp1 --with-lms --with-systemdsystemunitdir=/lib/systemd/system
13 |
14 | override_dh_strip:
15 | dh_strip --dbg-package=osmo-trx-dbg
16 |
--------------------------------------------------------------------------------
/debian/source/format:
--------------------------------------------------------------------------------
1 | 3.0 (native)
--------------------------------------------------------------------------------
/doc/Makefile.am:
--------------------------------------------------------------------------------
1 | SUBDIRS = \
2 | examples \
3 | manuals \
4 | $(NULL)
5 |
--------------------------------------------------------------------------------
/doc/examples/Makefile.am:
--------------------------------------------------------------------------------
1 | OSMOCONF_FILES =
2 | osmoconfdir = $(sysconfdir)/osmocom
3 |
4 | if DEVICE_UHD
5 | OSMOCONF_FILES += osmo-trx-uhd/osmo-trx-uhd.cfg
6 | endif
7 |
8 | # if DEVICE_USRP1
9 | # TODO: no usrp1 sample file yet
10 | # OSMOCONF_FILES += osmo-trx-usrp1/osmo-trx-usrp1.cfg
11 | # endif
12 |
13 | if DEVICE_LMS
14 | OSMOCONF_FILES += osmo-trx-lms/osmo-trx-lms.cfg
15 | endif
16 |
17 | osmoconf_DATA = $(OSMOCONF_FILES)
18 | EXTRA_DIST = $(OSMOCONF_FILES)
19 |
20 | CFG_FILES = find $(srcdir) -type f -name '*.cfg*' | sed -e 's,^$(srcdir),,'
21 |
22 | dist-hook:
23 | for f in $$($(CFG_FILES)); do \
24 | j="$(distdir)/$$f" && \
25 | mkdir -p "$$(dirname $$j)" && \
26 | $(INSTALL_DATA) $(srcdir)/$$f $$j; \
27 | done
28 |
29 | install-data-hook:
30 | for f in $$($(CFG_FILES)); do \
31 | j="$(DESTDIR)$(docdir)/examples/$$f" && \
32 | mkdir -p "$$(dirname $$j)" && \
33 | $(INSTALL_DATA) $(srcdir)/$$f $$j; \
34 | done
35 |
36 | uninstall-hook:
37 | @$(PRE_UNINSTALL)
38 | for f in $$($(CFG_FILES)); do \
39 | j="$(DESTDIR)$(docdir)/examples/$$f" && \
40 | $(RM) $$j; \
41 | done
42 |
--------------------------------------------------------------------------------
/doc/examples/osmo-trx-lms/osmo-trx-limesdr.cfg:
--------------------------------------------------------------------------------
1 | log stderr
2 | logging filter all 1
3 | logging color 1
4 | logging print category 1
5 | logging timestamp 1
6 | logging print file basename
7 | logging level set-all info
8 | !
9 | line vty
10 | no login
11 | !
12 | trx
13 | bind-ip 127.0.0.1
14 | remote-ip 127.0.0.1
15 | base-port 5700
16 | egprs disable
17 | tx-sps 4
18 | rx-sps 4
19 | rt-prio 18
20 | chan 0
21 | tx-path BAND1
22 | rx-path LNAW
23 |
--------------------------------------------------------------------------------
/doc/examples/osmo-trx-lms/osmo-trx-lms.cfg:
--------------------------------------------------------------------------------
1 | osmo-trx-limesdr.cfg
--------------------------------------------------------------------------------
/doc/examples/osmo-trx-uhd/osmo-trx-limesdr.cfg:
--------------------------------------------------------------------------------
1 | log stderr
2 | logging filter all 1
3 | logging color 1
4 | logging print category 1
5 | logging timestamp 1
6 | logging print file basename
7 | logging level set-all info
8 | !
9 | line vty
10 | no login
11 | !
12 | trx
13 | bind-ip 127.0.0.1
14 | remote-ip 127.0.0.1
15 | base-port 5700
16 | egprs disable
17 | tx-sps 4
18 | rx-sps 4
19 | rt-prio 18
20 | chan 0
21 | tx-path BAND1
22 | rx-path LNAW
23 |
--------------------------------------------------------------------------------
/doc/examples/osmo-trx-uhd/osmo-trx-uhd.cfg:
--------------------------------------------------------------------------------
1 | osmo-trx-usrp_b200.cfg
--------------------------------------------------------------------------------
/doc/examples/osmo-trx-uhd/osmo-trx-umtrx.cfg:
--------------------------------------------------------------------------------
1 | log stderr
2 | logging filter all 1
3 | logging color 1
4 | logging print category 1
5 | logging timestamp 1
6 | logging print file basename
7 | logging level set-all info
8 | !
9 | line vty
10 | no login
11 | !
12 | trx
13 | bind-ip 127.0.0.1
14 | remote-ip 127.0.0.1
15 | base-port 5700
16 | dev-args addr=192.168.10.2,pa=NONE,pa_power_max_dbm=23,fifo_ctrl_window=0,status_port=12345
17 | egprs disable
18 | tx-sps 4
19 | rx-sps 4
20 | rssi-offset 38
21 | rt-prio 18
22 | chan 0
23 | chan 1
24 |
--------------------------------------------------------------------------------
/doc/examples/osmo-trx-uhd/osmo-trx-usrp_b200.cfg:
--------------------------------------------------------------------------------
1 | log stderr
2 | logging filter all 1
3 | logging color 1
4 | logging print category 1
5 | logging timestamp 1
6 | logging print file basename
7 | logging level set-all info
8 | !
9 | line vty
10 | no login
11 | !
12 | trx
13 | bind-ip 127.0.0.1
14 | remote-ip 127.0.0.1
15 | base-port 5700
16 | egprs disable
17 | tx-sps 4
18 | rx-sps 4
19 | clock-ref external
20 | rt-prio 18
21 | chan 0
22 |
23 |
--------------------------------------------------------------------------------
/doc/manuals/Makefile.am:
--------------------------------------------------------------------------------
1 | EXTRA_DIST = osmotrx-usermanual.adoc \
2 | osmotrx-usermanual-docinfo.xml \
3 | osmotrx-vty-reference.xml \
4 | chapters \
5 | vty
6 |
7 | if BUILD_MANUALS
8 | ASCIIDOC = osmotrx-usermanual.adoc
9 | ASCIIDOC_DEPS = $(srcdir)/chapters/*.adoc
10 | include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
11 |
12 | VTY_REFERENCE = osmotrx-vty-reference.xml
13 | include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
14 |
15 | include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
16 | endif
17 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/configuration.adoc:
--------------------------------------------------------------------------------
1 | == Configuring OsmTRX
2 |
3 | OsmoTRX will read the configuration at startup time and configure the
4 | transceiver accordingly after validating the configuration.
5 |
6 | OsmoTRX can handle several TRX channels, but at least one must be configured in
7 | order to be able to start it successfully. Channels must be present in the
8 | configuration file in incremental order, starting from 0 and be consecutive.
9 |
10 | Example configuration files for different devices and setups can be found in
11 | `doc/examples/` in 'osmo-trx' git repository.
12 |
13 | === Documented example
14 |
15 | .Example: Static GGSN/APN configuration (single catch-all GGSN)
16 | ----
17 | trx
18 | bind-ip 127.0.0.1 <1>
19 | remote-ip 127.0.0.1 <2>
20 | base-port 5700 <3>
21 | egprs disable <4>
22 | tx-sps 4 <5>
23 | rx-sps 4 <6>
24 | chan 0 <7>
25 | tx-path BAND1 <8>
26 | rx-path LNAW <9>
27 | ----
28 | <1> Configure the local IP address at the TRX used for the connection against `osmo-bts-trx`.
29 | <2> Specify the IP address of `osmo-bts-trx` to connect to.
30 | <3> Specify the reference base UDP port to use for communication.
31 | <4> Don't enable EDGE support.
32 | <5> Use 4 TX samples per symbol. This is device specific.
33 | <6> Use 4 RX samples per symbol. This is device specific.
34 | <7> Configure the first channel. As no other channels are specified, `osmo-trx` assumes it is using only one channel.
35 | <8> Configure the device to use `BAND1` Tx antenna path from all the available ones (device specific).
36 | <9> Configure the device to use `LNAW` Rx antenna path from all the available ones (device specific).
37 |
38 | [[multiarfcn_mode]]
39 | === Multi-ARFCN mode
40 |
41 | The Multi-ARFCN feature allows to have a multi-carrier approach multiplexed on a
42 | single physical RF channel, which can introduce several benefits, such as lower
43 | cost and higher capacity support.
44 |
45 | Multi-ARFCN support is available since osmo-trx release `0.2.0`, and it was
46 | added specifically in commit `76764278169d252980853251daeb9f1ba0c246e1`.
47 |
48 | This feature is useful for instance if you want to run more than 1 TRX with an
49 | Ettus B200 device, or 3 TRX with an Ettus B210 device, since they support only 1
50 | and 2 physical RF channels respectively. No device from other providers or even
51 | other devices than B200 and B210 from Ettus are known to support this feature.
52 |
53 | With multi-ARFCN enabled, ARFCN spacing is fixed at 800 kHz or 4 GSM channels.
54 | So if TRX-0 is set to ARFCN 51, TRX-1 _must_ be set to 55, and so on. Up to
55 | three ARFCN's is supported for multi-TRX.
56 |
57 | From BTS and BSC point of view, supporting multiple TRX through multi-ARFCN
58 | feature in OsmoTRX doesn't make any difference from a regular multi-TRX setup,
59 | leaving apart of course the mentioned ARFCN limitations explained above and as a
60 | consequence physical installation and operational differences.
61 |
62 | .Example: osmo-bts-trx.cfg using 2 TRX against an osmo-trx driven device
63 | ----
64 | phy 0
65 | osmotrx ip local 127.0.0.1
66 | osmotrx ip remote 127.0.0.1
67 | instance 0
68 | instance 1
69 | bts 0
70 | ...
71 | band GSM-1800
72 | trx 0
73 | phy 0 instance 0
74 | trx 1
75 | phy 0 instance 1
76 | ----
77 |
78 | .Example: osmo-trx.cfg using Multi-ARFCN mode to run 2 TRX
79 | ----
80 | trx
81 | ...
82 | multi-arfcn enable
83 | chan 0
84 | chan 1
85 | ----
86 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/control.adoc:
--------------------------------------------------------------------------------
1 | [[control]]
2 | == Control interface
3 |
4 | The actual protocol is described in <>, the variables
5 | common to all programs using it are described in <>. Here we
6 | describe variables specific to OsmoTRX.
7 |
8 | .Variables available over control interface
9 | [options="header",width="100%",cols="20%,5%,5%,50%,20%"]
10 | |===
11 | |Name|Access|Trap|Value|Comment
12 | |===
13 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/counters.adoc:
--------------------------------------------------------------------------------
1 | [[counters]]
2 | == Counters
3 |
4 | include::./counters_generated.adoc[]
5 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/counters_generated.adoc:
--------------------------------------------------------------------------------
1 | // autogenerated by show asciidoc counters
2 | These counters and their description based on OsmoTRX 0.2.0.61-408f (OsmoTRX).
3 |
4 | // generating tables for rate_ctr_group
5 | // generating tables for osmo_stat_items
6 | // generating tables for osmo_counters
7 | // there are no ungrouped osmo_counters
8 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/overview.adoc:
--------------------------------------------------------------------------------
1 | [[chapter_introduction]]
2 | == Overview
3 |
4 | [[intro_overview]]
5 | === About OsmoTRX
6 |
7 | OsmoTRX is a C/C++ language implementation of the GSM radio modem,
8 | originally developed as the 'Transceiver' part of OpenBTS. This radio
9 | modem offers an interface based on top of UDP streams.
10 |
11 |
12 | The OsmoBTS bts_model code for OsmoTRX is called
13 | `osmo-bts-trx`. It implements the UDP stream interface of
14 | OsmoTRX, so both parts can be used together to implement a complete GSM
15 | BTS based on general-purpose computing SDR.
16 |
17 | As OsmoTRX is general-purpose software running on top of Linux, it is
18 | thus not tied to any specific physical hardware. At the time of this
19 | writing, OsmoTRX supports a variety of Lime Microsystems and Ettus USRP SDRs via
20 | the UHD driver, as well as the Fairwaves UmTRX and derived products.
21 |
22 | OsmoTRX is not a complete GSM PHY but 'just' the radio modem. This
23 | means that all of the Layer 1 functionality such as scheduling,
24 | convolutional coding, etc. is actually also implemented inside OsmoBTS.
25 | OsmoTRX is a software-defined radio transceiver that implements the Layer 1
26 | physical layer of a BTS comprising the following 3GPP specifications:
27 |
28 | * TS 05.01 "Physical layer on the radio path"
29 | * TS 05.02 "Multiplexing and Multiple Access on the Radio Path"
30 | * TS 05.04 "Modulation"
31 | * TS 05.10 "Radio subsystem synchronization
32 |
33 | As such, the boundary between OsmoTRX and `osmo-bts-trx` is at
34 | a much lower interface, which is an internal interface of other more
35 | traditional GSM PHY implementations.
36 |
37 | Besides OsmoTRX, there are also other implementations (both Free
38 | Software and proprietary) that implement the same UDP stream based radio
39 | modem interface.
40 |
41 | [[fig-gprs-pcubts]]
42 | .GSM network architecture with OsmoTRX and OsmoBTS
43 | [graphviz]
44 | ----
45 | digraph G {
46 | rankdir=LR;
47 | MS0 [label="MS"];
48 | MS1 [label="MS"];
49 | MS0->SDR[label="Um"];
50 | MS1->SDR [label="Um"];
51 | SDR -> OsmoTRX [label="Raw Samples"];
52 | OsmoTRX->BTS [label="bursts over UDP"];
53 | BTS->BSC [label="Abis"];
54 | BSC->MSC [label="A"];
55 | BTS->PCU [label="pcu_sock"];
56 | PCU->SGSN [label="Gb"];
57 | OsmoTRX [color=red];
58 | }
59 | ----
60 |
61 | For more information see
62 | https://osmocom.org/projects/osmotrx/wiki/OsmoTRX
63 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/running.adoc:
--------------------------------------------------------------------------------
1 | == Running OsmoTRX
2 |
3 | The OsmoTRX executable (`osmo-trx`) offers the following command-line
4 | options:
5 |
6 |
7 | === SYNOPSIS
8 |
9 | *osmo-trx* [-h] [-C 'CONFIGFILE']
10 |
11 |
12 | === OPTIONS
13 |
14 | *-h*::
15 | Print a short help message about the supported options
16 | *-C 'CONFIGFILE'*::
17 | Specify the file and path name of the configuration file to be
18 | used. If none is specified, use `osmo_trx.cfg` in the current
19 | working directory.
20 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/trx-architectures.adoc:
--------------------------------------------------------------------------------
1 | [[osmotrx_arch_support]]
2 | == OsmoTRX hardware architecture support
3 |
4 | OsmoTRX comes out-of-the-box with several algorithms and operations
5 | optimized for certain instruction-set architectures, as well as non-optimized
6 | fall-back algorithms in case required instruction sets are not supported by the
7 | compiler at compile time or by the executing machine at run-time. Support for
8 | these optimized algorithms can be enabled and disabled by means of configure
9 | flags. Accelerated operations include pulse shape filtering, resampling,
10 | sequence correlation, and many other signal processing operations.
11 |
12 | On Intel processors, OsmoTRX makes heavy use of the Streaming SIMD Extensions
13 | (SSE) instruction set. SSE3 is the minimum requirement for accelerated use.
14 | SSE3 is present in the majority of Intel processors since later versions of the
15 | Pentium 4 architecture and is also present on low power Atom processors. Support
16 | is automatically detected at build time. SSE4.1 instruction set is supported
17 | too. This feature is enabled by default unless explicitly disabled by passing
18 | the configure flag _--with-sse=no_. When enabled, the compiler will build an
19 | extra version of each of the supported algorithms using each of the supported
20 | mentioned instruction sets. Then, at run-time, OsmoTRX will auto-detect
21 | capabilities of the executing machine and enable an optimized algorithm using
22 | the most suitable available (previously compiled) instruction set.
23 |
24 | On ARM processors, NEON and NEON FMA are supported. Different to the x86, there
25 | is no auto-detection in this case, nor difference between compile and runtime.
26 | NEON support is disabled by default and can be enabled by passing the flag
27 | _--with-neon=yes_ to the configure script; the used compiler must support NEON
28 | instruction set and the resulting binary will only run fine on an ARM board
29 | supporting NEON extensions. Running OsmoTRX built with flag _--with-neon_ on a
30 | board without NEON instruction set support, will most probably end up in the
31 | process being killed with a _SIGILL_ Illegal Instruction signal by the operating
32 | system. NEON FMA (Fused Multiply-Add) is an extension to the NEON instruction
33 | set, and its use in OsmoTRX can be enabled by passing the _--with_neon_vfpv4_
34 | flag, which will also implicitly enable NEON support (_--with_neon_).
35 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/trx-backends.adoc:
--------------------------------------------------------------------------------
1 | [[trx_backends]]
2 | == OsmoTRX backend support
3 |
4 | [[backend_uhd]]
5 | === `osmo-trx-uhd` for UHD based Transceivers
6 |
7 | This OsmoTRX model uses _libuhd_ (UHD, USRP Hardware Driver) to drive the
8 | device, that is configuring it and reading/writing samples from/to it.
9 |
10 | So far, this backend has been mostly used to drive devices such as the Ettus
11 | B200 family and Fairwaves UmTRX family, and used to be the default backend used
12 | for legacy @osmo-trx@ binary when per-backend binaries didn't exist yet.
13 |
14 | Any device providing generic support for UHD should theoretically be able to be
15 | run through this backend without much effort, but pracitcal experience showed
16 | that some devices don't play well with it, such as the LimeSDR family of
17 | devices, which showed far better results when using its native interface.
18 |
19 | Related code can be found in the _Transceiver52M/device/uhd/_ directory in
20 | _osmo-trx.git_.
21 |
22 | [[backend_lms]]
23 | === `osmo-trx-lms` for LimeSuite based Transceivers
24 |
25 | This OsmoTRX model uses LimeSuite API and library to drive the device, that is
26 | configuring it and reading/writing samples from/to it.
27 |
28 | This backend was developed in order to be used together with LimeSDR-USB and
29 | LimeSDR-mini devices, due to to the poor results obtained with the UHD backend,
30 | and to simplify the stack.
31 |
32 | Related code can be found in the _Transceiver52M/device/lms/_ directory in
33 | _osmo-trx.git_.
34 |
35 | [[backend_usrp1]]
36 | === `osmo-trx-usrp1` for libusrp based Transceivers
37 |
38 | This OsmoTRX model uses the legacy libusrp driver provided in GNU Radio 3.4.2.
39 |
40 | As this code was dropped from GNU Radio at some point and was found very
41 | difficult to build, some work was done to create a standalone libusrp which can
42 | be nowadays found as a separate git repository together with other osmocom git
43 | repositories, in https://git.osmocom.org/libusrp/
44 |
45 | Related code can be found in the _Transceiver52M/device/usrp1/_ directory in
46 | _osmo-trx.git_.
47 |
--------------------------------------------------------------------------------
/doc/manuals/chapters/trx-devices.adoc:
--------------------------------------------------------------------------------
1 | [[osmotrx_device_support]]
2 | == OsmoTRX hardware device support
3 |
4 | OsmoTRX consists of a _common_ part that applies to all TRX devices as well as
5 | _hardware-specific_ parts for each TRX device. The hardware-specific parts are
6 | usually provided by vendor-specific or device-specific libraries that are then
7 | handled by some OsmoTRX glue code presenting a unified interface towards the
8 | rest of the code by means of a _RadioDevice_ class.
9 |
10 | The common part includes the core TRX architecture as well as code for
11 | implementing the external interfaces such as the TRX Manager UDP socket,
12 | control, and VTY interfaces.
13 |
14 | The hardware-specific parts include support for driving one particular
15 | implementation of a radio modem. Such a physical layer
16 | implementation can come in many forms. Sometimes it runs on a general
17 | purpose CPU, sometimes on a dedicated ARM core, a dedicated DSP, a
18 | combination of DSP and FPGA.
19 |
20 | Joining the common part with each of the available backends results in a
21 | different binary with different suffix for each backend. For instance, when
22 | OsmoTRX is built with UHD backend, an _osmo-trx-uhd_ binary is generated; when
23 | OsmoTRX is built with LimeSuite backend, an _osmo-trx-lms_ binary is generated.
24 | Build of different backend can be enabled and disabled by means of configure
25 | flags, which can be found in each subsection relative to each backend below.
26 |
27 | [[dev_ettus_usrp1]]
28 | === Ettus USRP1
29 |
30 | The binary _osmo-trx-usrp1_ is used to drive this device, see <>.
31 |
32 | [[dev_ettus_b200]]
33 | === Ettus B200
34 |
35 | The binary _osmo-trx-uhd_ is used to drive this device, see <>.
36 |
37 | Comes only with 1 RF channel. It can still be used in a multi-TRX setup by using
38 | the <> feature. By using this feature, one can drive up to 3
39 | TRX (with the restrictions explained there).
40 |
41 | [[dev_ettus_b200]]
42 | === Ettus B210
43 |
44 | The binary _osmo-trx-uhd_ is used to drive this device, see <>.
45 |
46 | Comes with 2 RF channels, which can be used to set up a multi-TRX BTS. However,
47 | due to a shared local oscillator for both RF channels, ARFCN separation can be
48 | up about 25 MHz.
49 |
50 | This device also supports the <> feature. By using this
51 | feature, one can drive up to 3 TRX (with the restrictions explained there).
52 | Please note that the above configurations cannot be combined, which means
53 | maximum number of TRX one can achieve is 2 by using separate physical RF
54 | channels, or 3 by using multi-ARFCN method. You cannot support, for example, 6
55 | ARFCN operation on B210 using 3 TRX on side A and another 3 TRX on side B.
56 |
57 | [[dev_limesdr_usb]]
58 | === LimeSDR-USB
59 |
60 | The binary _osmo-trx-lms_ is used to drive this device, see <>.
61 |
62 | This device comes with 2 RF channels, so it should theoretically be possible to
63 | run a multi-TRX setup with it, but there are yet no records that this kind of
64 | setup was tested with this device.
65 |
66 | This device has 3 different Rx paths with different antenna connectors in the
67 | PCB, each with a different frequency and bandwidth range. One should make sure
68 | the physical antenna is connected to the correct connector matching the Rx path
69 | you want to use. If one wants to be able to use the device in both 900 and 1800
70 | MHz GSM bands and easily switch between them, then Rx Path `LNAW` should be used
71 | ,since it is the only one covering both bands, and the antenna physically plugged
72 | accordingly. Following example shows how to then configure _osmo-trx-lms_ to use
73 | that Rx path to read samples.
74 |
75 | .Example: Configure osmo-trx-lms to use LNAW as Rx path and BAND1 as Tx Path
76 | ----
77 | trx
78 | ...
79 | chan 0
80 | tx-path BAND1
81 | rx-path LNAW
82 | ----
83 |
84 | [[dev_limesdr_mini]]
85 | === LimeSDR-mini
86 |
87 | The binary _osmo-trx-lms_ is used to drive this device, see <>.
88 |
89 | As a smaller brother of the [[dev_limesdr_usb]], this device comes only with 1
90 | RF channel. As a result, it can only hold 1 TRX as of today.
91 |
--------------------------------------------------------------------------------
/doc/manuals/osmotrx-usermanual-docinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 | March 6, 2019
5 | PE
6 |
7 | Initial version.
8 |
9 |
10 |
11 |
12 |
13 |
14 | Pau
15 | Espin Pedrol
16 | pespin@sysmocom.de
17 | PE
18 |
19 | sysmocom
20 | sysmocom - s.f.m.c. GmbH
21 | Software Developer
22 |
23 |
24 |
25 |
26 |
27 | 2018
28 | sysmocom - s.f.m.c. GmbH
29 |
30 |
31 |
32 |
33 | Permission is granted to copy, distribute and/or modify this
34 | document under the terms of the GNU Free Documentation License,
35 | Version 1.3 or any later version published by the Free Software
36 | Foundation; with no Invariant Sections, no Front-Cover Texts,
37 | and no Back-Cover Texts. A copy of the license is included in
38 | the section entitled "GNU Free Documentation License".
39 |
40 |
41 | The Asciidoc source code of this manual can be found at
42 |
43 | http://git.osmocom.org/osmo-gsm-manuals/
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/doc/manuals/osmotrx-usermanual.adoc:
--------------------------------------------------------------------------------
1 | :gfdl-enabled:
2 |
3 | OsmoTRX User Manual
4 | ====================
5 | Pau Espin Pedrol
6 |
7 |
8 | include::./common/chapters/preface.adoc[]
9 |
10 | include::{srcdir}/chapters/overview.adoc[]
11 |
12 | include::{srcdir}/chapters/running.adoc[]
13 |
14 | include::./common/chapters/control_if.adoc[]
15 |
16 | include::{srcdir}/chapters/control.adoc[]
17 |
18 | include::./common/chapters/vty.adoc[]
19 |
20 | include::./common/chapters/logging.adoc[]
21 |
22 | include::{srcdir}/chapters/counters.adoc[]
23 |
24 | include::{srcdir}/chapters/configuration.adoc[]
25 |
26 | include::{srcdir}/chapters/trx-architectures.adoc[]
27 |
28 | include::{srcdir}/chapters/trx-devices.adoc[]
29 |
30 | include::{srcdir}/chapters/trx-backends.adoc[]
31 |
32 | include::{srcdir}/chapters/code-architecture.adoc[]
33 |
34 | include::./common/chapters/trx_if.adoc[]
35 |
36 | include::./common/chapters/port_numbers.adoc[]
37 |
38 | include::./common/chapters/bibliography.adoc[]
39 |
40 | include::./common/chapters/glossary.adoc[]
41 |
42 | include::./common/chapters/gfdl.adoc[]
43 |
--------------------------------------------------------------------------------
/doc/manuals/osmotrx-vty-reference.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
10 | ]>
11 |
12 |
13 |
14 |
15 |
16 | v1
17 | 6th March 2018
18 | pe
19 | Initial
20 |
21 |
22 |
23 | OsmoTRX VTY Reference
24 |
25 |
26 | 2018
27 |
28 |
29 |
30 | This work is copyright by sysmocom - s.f.m.c. GmbH. All rights reserved.
31 |
32 |
33 |
34 |
35 |
36 | &chapter-vty;
37 |
38 |
--------------------------------------------------------------------------------
/doc/manuals/vty/trx_vty_additions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/tests/CommonLibs/BitVectorTest.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 |
27 |
28 |
29 | #include "BitVector.h"
30 | #include
31 | #include
32 |
33 | using namespace std;
34 |
35 |
36 | int main(int argc, char *argv[])
37 | {
38 | BitVector v5("000011110000");
39 | int r1 = v5.peekField(0,8);
40 | int r2 = v5.peekField(4,4);
41 | int r3 = v5.peekField(4,8);
42 | cout << r1 << ' ' << r2 << ' ' << r3 << endl;
43 | cout << v5 << endl;
44 | v5.fillField(0,0xa,4);
45 | int r4 = v5.peekField(0,8);
46 | cout << v5 << endl;
47 | cout << r4 << endl;
48 |
49 | v5.reverse8();
50 | cout << v5 << endl;
51 |
52 |
53 | unsigned char ts[9] = "abcdefgh";
54 | BitVector tp(70);
55 | cout << "ts=" << ts << endl;
56 | tp.unpack(ts);
57 | cout << "tp=" << tp << endl;
58 | tp.pack(ts);
59 | cout << "ts=" << ts << endl;
60 | }
61 |
--------------------------------------------------------------------------------
/tests/CommonLibs/BitVectorTest.ok:
--------------------------------------------------------------------------------
1 | 15 15 240
2 | 000011110000
3 | 101011110000
4 | 175
5 | 111101010000
6 | ts=abcdefgh
7 | tp=0110000101100010011000110110010001100101011001100110011101101000000000
8 | ts=abcdefgh
9 |
--------------------------------------------------------------------------------
/tests/CommonLibs/InterthreadTest.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 |
27 |
28 | #include "Threads.h"
29 | #include "Interthread.h"
30 | #include
31 |
32 | using namespace std;
33 |
34 |
35 | InterthreadQueue gQ;
36 | InterthreadMap gMap;
37 |
38 | int q_last_read_val = -1;
39 | int q_last_write_val;
40 | int m_last_read_val;
41 | int m_last_write_val;
42 |
43 | void* qWriter(void*)
44 | {
45 | int *p;
46 | for (int i=0; i<20; i++) {
47 | p = new int;
48 | *p = i;
49 | CERR("queue write " << *p);
50 | gQ.write(p);
51 | q_last_write_val = i;
52 | if (random()%2) sleep(1);
53 | }
54 | p = new int;
55 | *p = -1;
56 | gQ.write(p);
57 | return NULL;
58 | }
59 |
60 | void* qReader(void*)
61 | {
62 | bool done = false;
63 | while (!done) {
64 | int *p = gQ.read();
65 | CERR("queue read " << *p);
66 | if (*p<0) {
67 | assert(q_last_read_val == 19 && *p == -1);
68 | done = true;
69 | } else {
70 | assert(q_last_read_val == *p - 1);
71 | q_last_read_val = *p;
72 | }
73 | delete p;
74 | }
75 | return NULL;
76 | }
77 |
78 |
79 | void* mapWriter(void*)
80 | {
81 | int *p;
82 | for (int i=0; i<20; i++) {
83 | p = new int;
84 | *p = i;
85 | CERR("map write " << *p);
86 | gMap.write(i,p);
87 | m_last_write_val = i;
88 | if (random()%2) sleep(1);
89 | }
90 | return NULL;
91 | }
92 |
93 | void* mapReader(void*)
94 | {
95 | for (int i=0; i<20; i++) {
96 | int *p = gMap.read(i);
97 | CERR("map read " << *p);
98 | assert(*p == i);
99 | m_last_read_val = *p;
100 | // InterthreadMap will delete the pointers
101 | // delete p;
102 | }
103 | return NULL;
104 | }
105 |
106 |
107 |
108 |
109 |
110 |
111 | int main(int argc, char *argv[])
112 | {
113 | Thread qReaderThread;
114 | qReaderThread.start(qReader,NULL);
115 | Thread mapReaderThread;
116 | mapReaderThread.start(mapReader,NULL);
117 |
118 | Thread qWriterThread;
119 | qWriterThread.start(qWriter,NULL);
120 | Thread mapWriterThread;
121 | mapWriterThread.start(mapWriter,NULL);
122 |
123 | qReaderThread.join();
124 | qWriterThread.join();
125 | mapReaderThread.join();
126 | mapWriterThread.join();
127 |
128 | assert(q_last_write_val == 19);
129 | assert(q_last_read_val == 19);
130 | assert(m_last_write_val == 19);
131 | assert(m_last_read_val == 19);
132 |
133 | printf("Done\n");
134 | }
135 |
136 |
137 | // vim: ts=4 sw=4
138 |
--------------------------------------------------------------------------------
/tests/CommonLibs/InterthreadTest.ok:
--------------------------------------------------------------------------------
1 | Done
2 |
--------------------------------------------------------------------------------
/tests/CommonLibs/LogTest.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Free Software Foundation, Inc.
3 | * Copyright 2010 Kestrel Signal Processing, Inc.
4 | *
5 | *
6 | * This software is distributed under the terms of the GNU Affero Public License.
7 | * See the COPYING file in the main directory for details.
8 | *
9 | * This use of this software may be subject to additional restrictions.
10 | * See the LEGAL file in the main directory for details.
11 |
12 | This program is free software: you can redistribute it and/or modify
13 | it under the terms of the GNU Affero General Public License as published by
14 | the Free Software Foundation, either version 3 of the License, or
15 | (at your option) any later version.
16 |
17 | This program is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | GNU Affero General Public License for more details.
21 |
22 | You should have received a copy of the GNU Affero General Public License
23 | along with this program. If not, see .
24 |
25 | */
26 |
27 | #include
28 | #include
29 |
30 | #include "Logger.h"
31 | extern "C" {
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include "debug.h"
37 | }
38 |
39 | #define MYCAT 0
40 |
41 | int main(int argc, char *argv[])
42 | {
43 | struct log_info_cat categories[1];
44 | struct log_info linfo;
45 | categories[MYCAT] = {
46 | "MYCAT",
47 | NULL,
48 | "Whatever",
49 | LOGL_NOTICE,
50 | 1,
51 | };
52 | linfo.cat = categories;
53 | linfo.num_cat = ARRAY_SIZE(categories);
54 |
55 | void *tall_ctx = talloc_named_const(NULL, 1, "OsmoTRX context");
56 | msgb_talloc_ctx_init(tall_ctx, 0);
57 |
58 | osmo_init_logging2(tall_ctx, &linfo);
59 |
60 | log_set_use_color(osmo_stderr_target, 0);
61 | log_set_print_filename(osmo_stderr_target, 0);
62 | log_set_print_level(osmo_stderr_target, 1);
63 |
64 | Log(MYCAT, LOGL_FATAL, __BASE_FILE__, __LINE__).get() << "testing the logger.";
65 | Log(MYCAT, LOGL_ERROR, __BASE_FILE__, __LINE__).get() << "testing the logger.";
66 | Log(MYCAT, LOGL_NOTICE, __BASE_FILE__, __LINE__).get() << "testing the logger.";
67 | Log(MYCAT, LOGL_INFO, __BASE_FILE__, __LINE__).get() << "testing the logger.";
68 | Log(MYCAT, LOGL_DEBUG, __BASE_FILE__, __LINE__).get() << "testing the logger.";
69 | }
70 |
--------------------------------------------------------------------------------
/tests/CommonLibs/LogTest.err:
--------------------------------------------------------------------------------
1 | FATAL testing the logger.
2 | ERROR testing the logger.
3 | NOTICE testing the logger.
4 |
--------------------------------------------------------------------------------
/tests/CommonLibs/LogTest.ok:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttsou/osmo-trx/5e6f3e0cadf7859ae90073cd07afec550892a448/tests/CommonLibs/LogTest.ok
--------------------------------------------------------------------------------
/tests/CommonLibs/Makefile.am:
--------------------------------------------------------------------------------
1 | include $(top_srcdir)/Makefile.common
2 |
3 | AM_CPPFLAGS = -Wall -I$(top_srcdir)/CommonLibs $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) -g
4 | AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBOSMOVTY_LIBS)
5 |
6 | EXTRA_DIST = BitVectorTest.ok \
7 | PRBSTest.ok \
8 | InterthreadTest.ok \
9 | SocketsTest.ok \
10 | TimevalTest.ok \
11 | VectorTest.ok \
12 | LogTest.ok \
13 | LogTest.err
14 |
15 | noinst_PROGRAMS = \
16 | BitVectorTest \
17 | PRBSTest \
18 | InterthreadTest \
19 | SocketsTest \
20 | TimevalTest \
21 | VectorTest \
22 | LogTest
23 |
24 | BitVectorTest_SOURCES = BitVectorTest.cpp
25 | BitVectorTest_LDADD = $(COMMON_LA)
26 |
27 | PRBSTest_SOURCES = PRBSTest.cpp
28 |
29 | InterthreadTest_SOURCES = InterthreadTest.cpp
30 | InterthreadTest_LDADD = $(COMMON_LA)
31 | InterthreadTest_LDFLAGS = -lpthread $(AM_LDFLAGS)
32 |
33 | SocketsTest_SOURCES = SocketsTest.cpp
34 | SocketsTest_LDADD = $(COMMON_LA)
35 | SocketsTest_LDFLAGS = -lpthread $(AM_LDFLAGS)
36 |
37 | TimevalTest_SOURCES = TimevalTest.cpp
38 | TimevalTest_LDADD = $(COMMON_LA)
39 |
40 | VectorTest_SOURCES = VectorTest.cpp
41 | VectorTest_LDADD = $(COMMON_LA)
42 |
43 | LogTest_SOURCES = LogTest.cpp
44 | LogTest_LDADD = $(COMMON_LA)
45 |
46 | MOSTLYCLEANFILES += testSource testDestination
47 |
--------------------------------------------------------------------------------
/tests/CommonLibs/PRBSTest.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 Alexander Chemeris
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public
15 | * License along with this library; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | #include "PRBS.h"
20 | #include
21 | #include
22 | #include
23 |
24 | void testPrbs(PRBS &prbs, uint64_t expectedPeriod)
25 | {
26 | uint64_t period = 0;
27 | do {
28 | std::cout << prbs.generateBit();
29 | period++;
30 | } while (!prbs.isFinished());
31 | std::cout << std::endl;
32 | std::cout << "Period: " << period << std::endl;
33 | assert(period == expectedPeriod);
34 | }
35 |
36 | int main(int argc, char *argv[])
37 | {
38 | PRBS9 prbs9(0x01);
39 | testPrbs(prbs9, (1<<9)-1);
40 | PRBS15 prbs15(0x01);
41 | testPrbs(prbs15, (1<<15)-1);
42 | }
43 |
--------------------------------------------------------------------------------
/tests/CommonLibs/SocketsTest.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 |
27 |
28 |
29 | #include "Sockets.h"
30 | #include "Threads.h"
31 | #include
32 | #include
33 | #include
34 | #include
35 |
36 | static const int gNumToSend = 10;
37 |
38 | static void sigalarm_handler(int foo)
39 | {
40 | printf("FAIL: test did not run successfully\n");
41 | exit(EXIT_FAILURE);
42 | }
43 |
44 | void *testReaderIP(void *param)
45 | {
46 | UDPSocket *readSocket = (UDPSocket *)param;
47 | readSocket->nonblocking();
48 | int rc = 0;
49 | while (rcread(buf, MAX_UDP_LENGTH);
52 | if (count>0) {
53 | buf[count] = 0;
54 | CERR("read: " << buf);
55 | rc++;
56 | } else {
57 | sleep(2);
58 | }
59 | }
60 | return NULL;
61 | }
62 |
63 | int main(int argc, char * argv[] )
64 | {
65 | int count;
66 |
67 | if (signal(SIGALRM, sigalarm_handler) == SIG_ERR) {
68 | perror("signal");
69 | exit(EXIT_FAILURE);
70 | }
71 |
72 | /* If the test takes longer than 2*gNumToSend seconds, abort it */
73 | alarm(2* gNumToSend);
74 |
75 | UDPSocket readSocket("127.0.0.1", 0);
76 | UDPSocket socket1("127.0.0.1", 0, "localhost", readSocket.port());
77 |
78 | CERR("socket1: " << socket1.port() << ", readSocket: " << readSocket.port());
79 |
80 | Thread readerThreadIP;
81 | readerThreadIP.start(testReaderIP, &readSocket);
82 |
83 | // give the readers time to open
84 | sleep(1);
85 |
86 | for (int i=0; i.
23 |
24 | */
25 |
26 |
27 |
28 |
29 | #include "Timeval.h"
30 | #include
31 | #include
32 | #include
33 |
34 | extern "C" {
35 | #include
36 | }
37 |
38 | using namespace std;
39 |
40 | int main(int argc, char *argv[])
41 | {
42 |
43 | osmo_clock_override_enable(CLOCK_REALTIME, true);
44 |
45 | struct timespec *clk = osmo_clock_override_gettimespec(CLOCK_REALTIME);
46 | clk->tv_sec = 0;
47 | clk->tv_nsec = 1000;
48 |
49 | long last_remaining = 10000; /*10 sec */
50 | Timeval then(last_remaining);
51 | assert(then.elapsed() == -last_remaining);
52 | cerr << then << " elapsed: " << then.elapsed() << endl;
53 |
54 | /* Check that last_remaining parameter affects setting time in the future */
55 | osmo_clock_override_add(CLOCK_REALTIME, 0, 10*1000*1000);
56 | double increased_time_secs = Timeval().seconds();
57 | assert(increased_time_secs < then.seconds());
58 |
59 | struct timespec invariant_time = then.timespec();
60 | int loops = 0;
61 |
62 | while (!then.passed()) {
63 | struct timespec tspecnow = then.timespec();
64 | cerr << "["<< loops << "] now: " << Timeval().seconds() << " then: " << then << " remaining: " << then.remaining() << endl;
65 | assert(last_remaining >= then.remaining());
66 | assert(tspecnow.tv_sec == invariant_time.tv_sec && tspecnow.tv_nsec == invariant_time.tv_nsec);
67 | osmo_clock_override_add(CLOCK_REALTIME, 0, 500000*1000);
68 | loops++;
69 | }
70 | cerr << "now: " << Timeval() << " then: " << then << " remaining: " << then.remaining() << endl;
71 | assert(then.remaining() == -10);
72 | assert(loops == 20);
73 |
74 | printf("Done\n");
75 | }
76 |
--------------------------------------------------------------------------------
/tests/CommonLibs/TimevalTest.ok:
--------------------------------------------------------------------------------
1 | Done
2 |
--------------------------------------------------------------------------------
/tests/CommonLibs/VectorTest.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 Free Software Foundation, Inc.
3 | *
4 | *
5 | * This software is distributed under the terms of the GNU Affero Public License.
6 | * See the COPYING file in the main directory for details.
7 | *
8 | * This use of this software may be subject to additional restrictions.
9 | * See the LEGAL file in the main directory for details.
10 |
11 | This program is free software: you can redistribute it and/or modify
12 | it under the terms of the GNU Affero General Public License as published by
13 | the Free Software Foundation, either version 3 of the License, or
14 | (at your option) any later version.
15 |
16 | This program is distributed in the hope that it will be useful,
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Affero General Public License for more details.
20 |
21 | You should have received a copy of the GNU Affero General Public License
22 | along with this program. If not, see .
23 |
24 | */
25 |
26 |
27 |
28 | #include "Vector.h"
29 | #include
30 |
31 | using namespace std;
32 |
33 | typedef Vector TestVector;
34 |
35 | int main(int argc, char *argv[])
36 | {
37 | TestVector test1(5);
38 | for (int i=0; i<5; i++) test1[i]=i;
39 | TestVector test2(5);
40 | for (int i=0; i<5; i++) test2[i]=10+i;
41 |
42 | cout << test1 << endl;
43 | cout << test2 << endl;
44 |
45 | {
46 | TestVector testC(test1,test2);
47 | cout << testC << endl;
48 | cout << testC.head(3) << endl;
49 | cout << testC.tail(3) << endl;
50 | testC.fill(8);
51 | cout << testC << endl;
52 | test1.copyToSegment(testC,3);
53 | cout << testC << endl;
54 |
55 | TestVector testD(testC.segment(4,3));
56 | cout << testD << endl;
57 | testD.fill(9);
58 | cout << testC << endl;
59 | cout << testD << endl;
60 | }
61 |
62 | return 0;
63 | }
64 |
--------------------------------------------------------------------------------
/tests/CommonLibs/VectorTest.ok:
--------------------------------------------------------------------------------
1 | 0 1 2 3 4
2 | 10 11 12 13 14
3 | 0 1 2 3 4 10 11 12 13 14
4 | 0 1 2
5 | 3 4 10 11 12 13 14
6 | 8 8 8 8 8 8 8 8 8 8
7 | 8 8 8 0 1 2 3 4 8 8
8 | 1 2 3
9 | 8 8 8 0 9 9 9 4 8 8
10 | 9 9 9
11 |
--------------------------------------------------------------------------------
/tests/Makefile.am:
--------------------------------------------------------------------------------
1 | SUBDIRS = \
2 | CommonLibs \
3 | Transceiver52M \
4 | $(NULL)
5 |
6 | # The `:;' works around a Bash 3.2 bug when the output is not writeable.
7 | $(srcdir)/package.m4: $(top_srcdir)/configure.ac
8 | :;{ \
9 | echo '# Signature of the current package.' && \
10 | echo 'm4_define([AT_PACKAGE_NAME],' && \
11 | echo ' [$(PACKAGE_NAME)])' && \
12 | echo 'm4_define([AT_PACKAGE_TARNAME],' && \
13 | echo ' [$(PACKAGE_TARNAME)])' && \
14 | echo 'm4_define([AT_PACKAGE_VERSION],' && \
15 | echo ' [$(PACKAGE_VERSION)])' && \
16 | echo 'm4_define([AT_PACKAGE_STRING],' && \
17 | echo ' [$(PACKAGE_STRING)])' && \
18 | echo 'm4_define([AT_PACKAGE_BUGREPORT],' && \
19 | echo ' [$(PACKAGE_BUGREPORT)])'; \
20 | echo 'm4_define([AT_PACKAGE_URL],' && \
21 | echo ' [$(PACKAGE_URL)])'; \
22 | } >'$(srcdir)/package.m4'
23 |
24 | EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE)
25 | TESTSUITE = $(srcdir)/testsuite
26 | DISTCLEANFILES = atconfig $(NULL)
27 |
28 | check-local: atconfig $(TESTSUITE)
29 | $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS)
30 |
31 | installcheck-local: atconfig $(TESTSUITE)
32 | $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' $(TESTSUITEFLAGS)
33 |
34 | clean-local:
35 | test ! -f '$(TESTSUITE)' || $(SHELL) '$(TESTSUITE)' --clean
36 |
37 | AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te
38 | AUTOTEST = $(AUTOM4TE) --language=autotest
39 | $(TESTSUITE): $(srcdir)/testsuite.at $(srcdir)/package.m4
40 | $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
41 | mv $@.tmp $@
42 |
--------------------------------------------------------------------------------
/tests/Transceiver52M/LMSDeviceTest.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | extern "C"
6 | {
7 | size_t osmo_strlcpy(char *dst, const char *src, size_t siz);
8 | }
9 |
10 | int info_list_find(lms_info_str_t* info_list, unsigned int count, const std::string &args);
11 |
12 | using namespace std;
13 |
14 | int main(void)
15 | {
16 | unsigned int count;
17 | lms_info_str_t* info_list;
18 | std::string args;
19 |
20 | /* two fake entries for info_list */
21 | count = 2;
22 | info_list = new lms_info_str_t[count];
23 | osmo_strlcpy(info_list[0], "LimeSDR Mini, addr=24607:1337, serial=FAKESERIAL0001", sizeof(lms_info_str_t));
24 | osmo_strlcpy(info_list[1], "LimeSDR Mini, addr=24607:1338, serial=FAKESERIAL0002", sizeof(lms_info_str_t));
25 |
26 | /* find second entry by args filter */
27 | args = "serial=FAKESERIAL0002,LimeSDR Mini";
28 | assert(info_list_find(info_list, count, args) == 1);
29 |
30 | /* empty args -> first entry */
31 | args = "";
32 | assert(info_list_find(info_list, count, args) == 0);
33 |
34 | /* not matching args -> -1 */
35 | args = "serial=NOTMATCHING";
36 | assert(info_list_find(info_list, count, args) == -1);
37 |
38 | /* clean up */
39 | delete[] info_list;
40 | return 0;
41 | }
42 |
--------------------------------------------------------------------------------
/tests/Transceiver52M/Makefile.am:
--------------------------------------------------------------------------------
1 | include $(top_srcdir)/Makefile.common
2 |
3 | AM_CFLAGS = -Wall -I$(top_srcdir)/Transceiver52M -I$(top_srcdir)/Transceiver52M/arch/common $(STD_DEFINES_AND_INCLUDES) -g
4 |
5 | EXTRA_DIST = convolve_test.ok convolve_test_golden.h
6 |
7 | noinst_PROGRAMS = \
8 | convolve_test
9 |
10 | convolve_test_SOURCES = convolve_test.c
11 | convolve_test_CFLAGS = $(AM_CFLAGS)
12 | convolve_test_LDADD = $(COMMON_LA) $(ARCH_LA)
13 | if HAVE_SSE3
14 | convolve_test_CFLAGS += $(SIMD_FLAGS)
15 | endif
16 | if HAVE_SSE4_1
17 | convolve_test_CFLAGS += $(SIMD_FLAGS)
18 | endif
19 |
20 | if DEVICE_LMS
21 | noinst_PROGRAMS += LMSDeviceTest
22 | LMSDeviceTest_SOURCES = LMSDeviceTest.cpp
23 | LMSDeviceTest_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LMS_LIBS)
24 | LMSDeviceTest_LDADD = \
25 | $(top_builddir)/Transceiver52M/device/lms/libdevice.la \
26 | $(COMMON_LA) \
27 | $(LMS_LIBS)
28 | LMSDeviceTest_CPPFLAGS = $(AM_CPPFLAGS) $(LMS_CFLAGS)
29 | endif
30 |
--------------------------------------------------------------------------------
/tests/testsuite.at:
--------------------------------------------------------------------------------
1 | AT_INIT
2 | AT_BANNER([Regression tests.])
3 |
4 | AT_SETUP([LMSDeviceTest])
5 | AT_KEYWORDS([LMSDeviceTest])
6 | AT_SKIP_IF([! test -e $abs_top_builddir/tests/Transceiver52M/LMSDeviceTest])
7 | AT_CHECK([$abs_top_builddir/tests/Transceiver52M/LMSDeviceTest], [], [], [])
8 | AT_CLEANUP
9 |
10 | AT_SETUP([BitVectorTest])
11 | AT_KEYWORDS([BitVectorTest])
12 | cat $abs_srcdir/CommonLibs/BitVectorTest.ok > expout
13 | AT_CHECK([$abs_top_builddir/tests/CommonLibs/BitVectorTest], [], [expout], [])
14 | AT_CLEANUP
15 |
16 | AT_SETUP([InterthreadTest])
17 | AT_KEYWORDS([InterthreadTest])
18 | cat $abs_srcdir/CommonLibs/InterthreadTest.ok > expout
19 | AT_CHECK([$abs_top_builddir/tests/CommonLibs/InterthreadTest], [], [expout], [ignore])
20 | AT_CLEANUP
21 |
22 | AT_SETUP([LogTest])
23 | AT_KEYWORDS([LogTest])
24 | cat $abs_srcdir/CommonLibs/LogTest.ok > expout
25 | cat $abs_srcdir/CommonLibs/LogTest.err > experr
26 | AT_CHECK([$abs_top_builddir/tests/CommonLibs/LogTest], [], [expout], [experr])
27 | AT_CLEANUP
28 |
29 | AT_SETUP([PRBSTest])
30 | AT_KEYWORDS([PRBSTest])
31 | cat $abs_srcdir/CommonLibs/PRBSTest.ok > expout
32 | AT_CHECK([$abs_top_builddir/tests/CommonLibs/PRBSTest], [], [expout], [])
33 | AT_CLEANUP
34 |
35 | AT_SETUP([SocketsTest])
36 | AT_KEYWORDS([SocketsTest])
37 | cat $abs_srcdir/CommonLibs/SocketsTest.ok > expout
38 | AT_CHECK([$abs_top_builddir/tests/CommonLibs/SocketsTest], [], [expout], [ignore])
39 | AT_CLEANUP
40 |
41 | AT_SETUP([TimevalTest])
42 | AT_KEYWORDS([TimevalTest])
43 | cat $abs_srcdir/CommonLibs/TimevalTest.ok > expout
44 | AT_CHECK([$abs_top_builddir/tests/CommonLibs/TimevalTest], [], [expout], [ignore])
45 | AT_CLEANUP
46 |
47 | AT_SETUP([VectorTest])
48 | AT_KEYWORDS([VectorTest])
49 | cat $abs_srcdir/CommonLibs/VectorTest.ok > expout
50 | AT_CHECK([$abs_top_builddir/tests/CommonLibs/VectorTest], [], [expout], [])
51 | AT_CLEANUP
52 |
53 | AT_SETUP([convolve_test])
54 | AT_KEYWORDS([convolve_test])
55 | cat $abs_srcdir/Transceiver52M/convolve_test.ok > expout
56 | AT_CHECK([$abs_top_builddir/tests/Transceiver52M/convolve_test], [], [expout], [])
57 | AT_CLEANUP
58 |
--------------------------------------------------------------------------------
/utils/clockdump.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | sudo tcpdump -i lo0 -A udp port 5700
3 |
4 |
--------------------------------------------------------------------------------