├── .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 | --------------------------------------------------------------------------------