mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
				synced 2025-11-03 21:53:18 +00:00 
			
		
		
		
	Compare commits
	
		
			30 Commits
		
	
	
		
			fairwaves/
			...
			fairwaves/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b54d46e670 | ||
| 
						 | 
					8c490f5f0b | ||
| 
						 | 
					835841853f | ||
| 
						 | 
					e7c25a3677 | ||
| 
						 | 
					6d17a6a7e6 | ||
| 
						 | 
					bb8d46adaa | ||
| 
						 | 
					20b388973c | ||
| 
						 | 
					0d039e2676 | ||
| 
						 | 
					ad669513d2 | ||
| 
						 | 
					fd978b28bd | ||
| 
						 | 
					1b6aaae3fa | ||
| 
						 | 
					facdadc254 | ||
| 
						 | 
					eefa8e58f7 | ||
| 
						 | 
					3ac1cbf40e | ||
| 
						 | 
					139c84564c | ||
| 
						 | 
					2cb6070e09 | ||
| 
						 | 
					f2bdd1a24c | ||
| 
						 | 
					34e5a3807f | ||
| 
						 | 
					b49874aa64 | ||
| 
						 | 
					030951695c | ||
| 
						 | 
					b721d6104d | ||
| 
						 | 
					c19d1f6c36 | ||
| 
						 | 
					f0d8a581b4 | ||
| 
						 | 
					37b445d4c8 | ||
| 
						 | 
					df127bc74e | ||
| 
						 | 
					6512812e43 | ||
| 
						 | 
					ded68da44f | ||
| 
						 | 
					37bbfa2125 | ||
| 
						 | 
					fdbf914584 | ||
| 
						 | 
					bbef7e4d70 | 
@@ -193,7 +193,7 @@ Log::~Log()
 | 
				
			|||||||
	if (mDummyInit) return;
 | 
						if (mDummyInit) return;
 | 
				
			||||||
	// Anything at or above LOG_CRIT is an "alarm".
 | 
						// Anything at or above LOG_CRIT is an "alarm".
 | 
				
			||||||
	// Save alarms in the local list and echo them to stderr.
 | 
						// Save alarms in the local list and echo them to stderr.
 | 
				
			||||||
	if (mPriority <= LOG_CRIT) {
 | 
						if (mPriority <= LOG_ERR) {
 | 
				
			||||||
		if (sLoggerInited) addAlarm(mStream.str().c_str());
 | 
							if (sLoggerInited) addAlarm(mStream.str().c_str());
 | 
				
			||||||
		cerr << mStream.str() << endl;
 | 
							cerr << mStream.str() << endl;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -206,7 +206,7 @@ Log::~Log()
 | 
				
			|||||||
	if (gLogToConsole||gLogToFile) {
 | 
						if (gLogToConsole||gLogToFile) {
 | 
				
			||||||
		int mlen = mStream.str().size();
 | 
							int mlen = mStream.str().size();
 | 
				
			||||||
		int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
 | 
							int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
 | 
				
			||||||
		gLogToLock.lock();
 | 
							ScopedLock lock(gLogToLock);
 | 
				
			||||||
		if (gLogToConsole) {
 | 
							if (gLogToConsole) {
 | 
				
			||||||
			// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
 | 
								// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
 | 
				
			||||||
			// so just use std::cout.
 | 
								// so just use std::cout.
 | 
				
			||||||
@@ -218,7 +218,6 @@ Log::~Log()
 | 
				
			|||||||
			if (neednl) {fputc('\n',gLogToFile);}
 | 
								if (neednl) {fputc('\n',gLogToFile);}
 | 
				
			||||||
			fflush(gLogToFile);
 | 
								fflush(gLogToFile);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		gLogToLock.unlock();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										260
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										260
									
								
								README
									
									
									
									
									
								
							@@ -1,168 +1,116 @@
 | 
				
			|||||||
Welcome to the OpenBTS source code.
 | 
					This is the interface to the transcevier.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each TRX Manager UDP socket interface represents a single ARFCN.
 | 
				
			||||||
For free support, please subscribe to openbts-discuss@lists.sourceforge.net.
 | 
					Each of these per-ARFCN interfaces is a pair of UDP sockets, one for control and one for data.
 | 
				
			||||||
See http://sourceforge.net/mailarchive/forum.php?forum_name=openbts-discuss
 | 
					Give a base port B (5700), the master clock interface is at port P=B.
 | 
				
			||||||
and https://lists.sourceforge.net/lists/listinfo/openbts-discuss for details.
 | 
					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.
 | 
				
			||||||
 | 
					The corresponding core-side interface for every socket is at P+100.
 | 
				
			||||||
For additional information, refer to http://openbts.org.
 | 
					For any given build, the number of ARFCN interfaces can be fixed.
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
These are the directories:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AsteriskConfig	Asterisk configuration files for use with OpenBTS.
 | 
					 | 
				
			||||||
CommonLib	Common-use libraries, mostly C++ wrappers for basic facilities.
 | 
					 | 
				
			||||||
Control		Control-layer functions for the protocols of GSM 04.08 and SIP.
 | 
					 | 
				
			||||||
GSM		The GSM stack.
 | 
					 | 
				
			||||||
SIP		Components of the SIP state machines ued by the control layer.
 | 
					 | 
				
			||||||
SMS		The SMS stack.
 | 
					 | 
				
			||||||
SR		The subscriber registry.
 | 
					 | 
				
			||||||
TRXManager	The interface between the GSM stack and the radio.
 | 
					 | 
				
			||||||
Transceiver	The software transceiver and specific installation tests.
 | 
					 | 
				
			||||||
apps		OpenBTS application binaries.
 | 
					 | 
				
			||||||
doc		Project documentation.
 | 
					 | 
				
			||||||
tests		Test fixtures for subsets of OpenBTS components.
 | 
					 | 
				
			||||||
smqueue		RFC-3428 store-and-forward server for SMS
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
By default, OpenBTS assumes the following UDP port assignments:
 | 
					Indications on the Master Clock Interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
5060 -- Asterisk SIP interface
 | 
					The master clock interface is output only (from the radio).
 | 
				
			||||||
5061 -- local SIP softphone
 | 
					Messages are "indications".
 | 
				
			||||||
5062 -- OpenBTS SIP interface
 | 
					 | 
				
			||||||
5063 -- smqueue SIP interface
 | 
					 | 
				
			||||||
5064 -- subscriber registry SIP interface
 | 
					 | 
				
			||||||
5700-range -- OpenBTS-transceiver interface
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
These can be controlled in the CONFIG table in /etc/OpenBTS.db.
 | 
					CLOCK gives the current value of the transceiver clock to be used by the core.
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
 | 
					IND CLOCK <totalFrames>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Standrd paths:
 | 
					 | 
				
			||||||
/OpenBTS -- Binary installation.
 | 
					 | 
				
			||||||
/etc/OpenBTS -- Configuration databases.
 | 
					 | 
				
			||||||
/var/run/OpenBTS -- Real-time reporting databases.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The script apps/setUpFiles.sh will create these directories and install the
 | 
					
 | 
				
			||||||
correct files in them.
 | 
					Commands on the Per-ARFCN Control Interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The per-ARFCN control interface uses a command-reponse protocol.
 | 
				
			||||||
 | 
					Commands are NULL-terminated ASCII strings, one per UDP socket.
 | 
				
			||||||
 | 
					Each command has a corresponding response.
 | 
				
			||||||
 | 
					Every command is of the form:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CMD <cmdtype> [params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The <cmdtype> is the actual command.
 | 
				
			||||||
 | 
					Parameters are optional depending on the commands type.
 | 
				
			||||||
 | 
					Every response is of the form:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RSP <cmdtype> <status> [result]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The <status> is 0 for success and a non-zero error code for failure.
 | 
				
			||||||
 | 
					Successful responses may include results, depending on the command type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Power Control
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					POWEROFF shuts off transmitter power and stops the demodulator.
 | 
				
			||||||
 | 
					CMD POWEROFF
 | 
				
			||||||
 | 
					RSP POWEROFF <status>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					POWERON starts the transmitter and starts the demodulator.  Initial power level is very low.
 | 
				
			||||||
 | 
					This command fails if the transmitter and receiver are not yet tuned.
 | 
				
			||||||
 | 
					This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
 | 
				
			||||||
 | 
					If the transceiver is already on, it response with success to this command.
 | 
				
			||||||
 | 
					CMD POWERON
 | 
				
			||||||
 | 
					RSP POWERON <status>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SETPOWER sets output power in dB wrt full scale.
 | 
				
			||||||
 | 
					This command fails if the transmitter and receiver are not running.
 | 
				
			||||||
 | 
					CMD SETPOWER <dB>
 | 
				
			||||||
 | 
					RSP SETPOWER <status> <dB>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ADJPOWER adjusts power by the given dB step.  Response returns resulting power level wrt full scale.
 | 
				
			||||||
 | 
					This command fails if the transmitter and receiver are not running.
 | 
				
			||||||
 | 
					CMD ADJPOWER <dBStep>
 | 
				
			||||||
 | 
					RSP ADJPOWER <status> <dBLevel>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tuning Control
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RXTUNE tunes the receiver to a given frequency in kHz.
 | 
				
			||||||
 | 
					This command fails if the receiver is already running.
 | 
				
			||||||
 | 
					(To re-tune you stop the radio, re-tune, and restart.)
 | 
				
			||||||
 | 
					This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
 | 
				
			||||||
 | 
					CMD RXTUNE <kHz>
 | 
				
			||||||
 | 
					RSP RXTUNE <status> <kHz>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TXTUNE tunes the transmitter to a given frequency in kHz.
 | 
				
			||||||
 | 
					This command fails if the transmitter is already running.
 | 
				
			||||||
 | 
					(To re-tune you stop the radio, re-tune, and restart.)
 | 
				
			||||||
 | 
					This command fails if the transmit or receive frequency creates a conflict with another ARFCN that is already runnng.
 | 
				
			||||||
 | 
					CMD TXTUNE <kHz>
 | 
				
			||||||
 | 
					RSP TXTUNE <status> <kHz>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timeslot Control
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SETSLOT sets the format of the uplink timeslots in the ARFCN.
 | 
				
			||||||
 | 
					The <timeslot> indicates the timeslot of interest.
 | 
				
			||||||
 | 
					The <chantype> indicates the type of channel that occupies the timeslot.
 | 
				
			||||||
 | 
					A chantype of zero indicates the timeslot is off.
 | 
				
			||||||
 | 
					CMD SETSLOT <timeslot> <chantype>
 | 
				
			||||||
 | 
					RSP SETSLOT <status> <timeslot> <chantype>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Messages on the per-ARFCN Data Interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Messages on the data interface carry one radio burst per UDP message.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Received Data Burst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1 byte timeslot index
 | 
				
			||||||
 | 
					4 bytes GSM frame number, big endian
 | 
				
			||||||
 | 
					1 byte RSSI in -dBm
 | 
				
			||||||
 | 
					2 bytes correlator timing offset in 1/256 symbol steps, 2's-comp, big endian
 | 
				
			||||||
 | 
					148 bytes soft symbol estimates, 0 -> definite "0", 255 -> definite "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Transmit Data Burst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1 byte timeslot index
 | 
				
			||||||
 | 
					4 bytes GSM frame number, big endian
 | 
				
			||||||
 | 
					1 byte transmit level wrt ARFCN max, -dB (attenuation)
 | 
				
			||||||
 | 
					148 bytes output symbol values, 0 & 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Release history:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Release	Name		SVN Reposiory	SVN Rev	Comments
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.0	(none)		SF.net		??		completed L1, L2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.1	Arnaudville	GNU Radio	r10019 (trunk)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.2	Breaux Bridge	GNU Radio	r10088 (trunk)	GNU Build, very early assignment
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.3	Carencro	KSP		r1 (trunk)	first post-injunction release
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.4	Donaldsonville	KSP		r23 (trunk)	fixed Ubuntu build error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.5	Eunice		KSP		r39 (trunk)	fixed L2 bugs related to segmentation
 | 
					 | 
				
			||||||
							removed incomplete SMS directory
 | 
					 | 
				
			||||||
							moved "abort" calls into L3 subclasses
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1.6	New Iberia	KSP		r130 (trunk)	import of all 2.2 improvements to non-SMS release
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.0	St. Francisville KSP		r54 (smswork)	SMS support
 | 
					 | 
				
			||||||
							file-based configuration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.1	Grand Coteau	KSP		r70 (smswork)	DTMF support
 | 
					 | 
				
			||||||
							fixed more Linux-related build errors
 | 
					 | 
				
			||||||
								-lpthread
 | 
					 | 
				
			||||||
								TLMessage constructor
 | 
					 | 
				
			||||||
							expanded stack to prevent overflows in Linux
 | 
					 | 
				
			||||||
							moved gSIPInterface to main app
 | 
					 | 
				
			||||||
							fixed iterator bug in Pager
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.2	Houma		KSP		r122 (smswork)	added LEGAL notice
 | 
					 | 
				
			||||||
							removed Assert classes
 | 
					 | 
				
			||||||
							stop paging on page response
 | 
					 | 
				
			||||||
							fixed Pager-spin bug
 | 
					 | 
				
			||||||
							fixed Transceiver spin bugs
 | 
					 | 
				
			||||||
							fixed 2^32 microsecond rollover bug
 | 
					 | 
				
			||||||
							reduced stack footprints in Transceiver
 | 
					 | 
				
			||||||
							fixed SMS timestamps
 | 
					 | 
				
			||||||
							check LAI before using TMSI in LUR
 | 
					 | 
				
			||||||
							reduced memory requirement by 75%
 | 
					 | 
				
			||||||
							removed PagerTest
 | 
					 | 
				
			||||||
							fixed stale-transaction bug in paging handler
 | 
					 | 
				
			||||||
							fixed USRP clock rollover bug
 | 
					 | 
				
			||||||
							faster call connection
 | 
					 | 
				
			||||||
							new USRPDevice design
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.3	Jean Lafitte	KSP		r190? (trunk)	check for out-of-date RACH bursts
 | 
					 | 
				
			||||||
							better TRX-GSM clock sync
 | 
					 | 
				
			||||||
							formal logging system
 | 
					 | 
				
			||||||
							command line interface
 | 
					 | 
				
			||||||
							emergency call setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.4	Kinder		KSP		r208? (trunk)	fixed BCCH neighbor list bug
 | 
					 | 
				
			||||||
							support for neighbor lists
 | 
					 | 
				
			||||||
							fixed support for non-local Asterisk servers
 | 
					 | 
				
			||||||
							cleaner configuration management
 | 
					 | 
				
			||||||
							more realtime control of BCCH parameters
 | 
					 | 
				
			||||||
							proper rejection of Hold messages
 | 
					 | 
				
			||||||
							fixed L3 hanging bug in MTDCheckBYE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.4.1	Kinder		KSP		r462		fixed lots of valgrind errors
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.4.2	Kinder		KSP		r482		zero-length calling party number bug
 | 
					 | 
				
			||||||
							g++ 4.4 #includes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.5	Lacassine	KSP		r551		imported Joshua Lackey patches
 | 
					 | 
				
			||||||
							SIP fixes from Anne Kwong
 | 
					 | 
				
			||||||
							SIP fixes from testing with SMS server
 | 
					 | 
				
			||||||
							L3 TI handling fixes
 | 
					 | 
				
			||||||
							SMS server support
 | 
					 | 
				
			||||||
							GNU Radio 3.2 compatibility
 | 
					 | 
				
			||||||
							configurable max range and LU-reject cause
 | 
					 | 
				
			||||||
							"page" & "testcall" CLI features
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.5.1	Lacassine	KSP		r595		fixed some build bugs for some Linux distros
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.5.2	Lacassine	KSP		r630		fixed channel assignment bug for Nokia DCT4+ handsets
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.5.3	Lacassine	KSP		r756		merged fix for transceiver startup crash
 | 
					 | 
				
			||||||
								due to use of uninitialized variables (r646)
 | 
					 | 
				
			||||||
							merged fix for fusb bug from trunk (r582)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.5.4	Lacassine	KSP		r812		merged fixes to build under latest Fedora and
 | 
					 | 
				
			||||||
								to build with git GnuRadio (r814)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.6	Mamou		KSP		r886		fixed infamous fusb bug (r582)
 | 
					 | 
				
			||||||
							fixed idle-filling table size bug
 | 
					 | 
				
			||||||
							smoother uplink power control
 | 
					 | 
				
			||||||
							load-limiting downlink power control
 | 
					 | 
				
			||||||
							new "config" features (optional, static)
 | 
					 | 
				
			||||||
							IMEI interrogation
 | 
					 | 
				
			||||||
							fixed MOD "missing FIFO" bug
 | 
					 | 
				
			||||||
							configurable short code features
 | 
					 | 
				
			||||||
							fixed transceiver startup crash (r646)
 | 
					 | 
				
			||||||
							readline support is back
 | 
					 | 
				
			||||||
							fixed timing advance bug (r844)
 | 
					 | 
				
			||||||
							added CLI "chans" command
 | 
					 | 
				
			||||||
							track time-of-use in TMSI table (r844)
 | 
					 | 
				
			||||||
							added CLI "noise" command (r844)
 | 
					 | 
				
			||||||
							added CLI "rxpower" command (r844)
 | 
					 | 
				
			||||||
							added CLI "unconfig" command
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.7	Natchitoches	Range	rxxx			(never released publicly)
 | 
					 | 
				
			||||||
							converted TMSITable to sqlite3 (r902)
 | 
					 | 
				
			||||||
							sqlite3-based configuration (r???)
 | 
					 | 
				
			||||||
							converted Logger to syslogd (r903)
 | 
					 | 
				
			||||||
							added support for rest octets (r1022)
 | 
					 | 
				
			||||||
							external database for transaction reporting (r1184)
 | 
					 | 
				
			||||||
							external database for channel status reporting (r1203)
 | 
					 | 
				
			||||||
							in-call delivery and submission of text messages (r1231)
 | 
					 | 
				
			||||||
							RFC-2833 DMTF (r1249)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2.8	Opelousas	Range	rxxx			move databases to /etc and /var
 | 
					 | 
				
			||||||
							RRLP aiding support
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,8 @@
 | 
				
			|||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <iomanip>      // std::setprecision
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
#include "Transceiver.h"
 | 
					#include "Transceiver.h"
 | 
				
			||||||
#include <Logger.h>
 | 
					#include <Logger.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -143,15 +145,22 @@ Transceiver::Transceiver(int wBasePort,
 | 
				
			|||||||
                         const char *wTRXAddress,
 | 
					                         const char *wTRXAddress,
 | 
				
			||||||
                         size_t wSPS, size_t wChans,
 | 
					                         size_t wSPS, size_t wChans,
 | 
				
			||||||
                         GSM::Time wTransmitLatency,
 | 
					                         GSM::Time wTransmitLatency,
 | 
				
			||||||
			 RadioInterface *wRadioInterface)
 | 
					                         RadioInterface *wRadioInterface,
 | 
				
			||||||
 | 
					                         double wRssiOffset)
 | 
				
			||||||
  : mBasePort(wBasePort), mAddr(wTRXAddress),
 | 
					  : mBasePort(wBasePort), mAddr(wTRXAddress),
 | 
				
			||||||
    mClockSocket(wBasePort, wTRXAddress, mBasePort + 100),
 | 
					    mClockSocket(wBasePort, wTRXAddress, mBasePort + 100),
 | 
				
			||||||
    mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
 | 
					    mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
 | 
				
			||||||
 | 
					    rssiOffset(wRssiOffset),
 | 
				
			||||||
    mSPSTx(wSPS), mSPSRx(1), mChans(wChans), mOn(false),
 | 
					    mSPSTx(wSPS), mSPSRx(1), mChans(wChans), mOn(false),
 | 
				
			||||||
    mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelay(0)
 | 
					    mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelay(0), mWriteBurstToDiskMask(0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  txFullScale = mRadioInterface->fullScaleInputValue();
 | 
					  txFullScale = mRadioInterface->fullScaleInputValue();
 | 
				
			||||||
  rxFullScale = mRadioInterface->fullScaleOutputValue();
 | 
					  rxFullScale = mRadioInterface->fullScaleOutputValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (int i = 0; i < 8; i++) {
 | 
				
			||||||
 | 
					    for (int j = 0; j < 8; j++)
 | 
				
			||||||
 | 
					      mHandover[i][j] = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Transceiver::~Transceiver()
 | 
					Transceiver::~Transceiver()
 | 
				
			||||||
@@ -459,9 +468,15 @@ void Transceiver::setModulus(size_t timeslot, size_t chan)
 | 
				
			|||||||
Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
 | 
					Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
 | 
				
			||||||
                                                    size_t chan)
 | 
					                                                    size_t chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  static int tchh_subslot[26] = { 0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,1 };
 | 
				
			||||||
 | 
					  static int sdcch4_subslot[102] = { 3,3,3,3,0,0,2,2,2,2,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2,
 | 
				
			||||||
 | 
					                                     3,3,3,3,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2,2,2 };
 | 
				
			||||||
 | 
					  static int sdcch8_subslot[102] = { 5,5,5,5,6,6,6,6,7,7,7,7,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,0,0,0,0,
 | 
				
			||||||
 | 
					                                     1,1,1,1,2,2,2,2,3,3,3,3,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,4,4,4,4 };
 | 
				
			||||||
  TransceiverState *state = &mStates[chan];
 | 
					  TransceiverState *state = &mStates[chan];
 | 
				
			||||||
  unsigned burstTN = currTime.TN();
 | 
					  unsigned burstTN = currTime.TN();
 | 
				
			||||||
  unsigned burstFN = currTime.FN();
 | 
					  unsigned burstFN = currTime.FN();
 | 
				
			||||||
 | 
					  int subch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch (state->chanType[burstTN]) {
 | 
					  switch (state->chanType[burstTN]) {
 | 
				
			||||||
  case NONE:
 | 
					  case NONE:
 | 
				
			||||||
@@ -471,16 +486,25 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
 | 
				
			|||||||
    return IDLE;
 | 
					    return IDLE;
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case I:
 | 
					  case I:
 | 
				
			||||||
 | 
					    // TODO: Are we expecting RACH on an IDLE frame?
 | 
				
			||||||
 | 
					/*    if (burstFN % 26 == 25)
 | 
				
			||||||
 | 
					      return IDLE;*/
 | 
				
			||||||
 | 
					    if (mHandover[burstTN][0])
 | 
				
			||||||
 | 
					      return RACH;
 | 
				
			||||||
    return TSC;
 | 
					    return TSC;
 | 
				
			||||||
    /*if (burstFN % 26 == 25) 
 | 
					 | 
				
			||||||
      return IDLE;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      return TSC;*/
 | 
					 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case II:
 | 
					  case II:
 | 
				
			||||||
 | 
					    subch = tchh_subslot[burstFN % 26];
 | 
				
			||||||
 | 
					    if (subch == 1)
 | 
				
			||||||
 | 
					      return IDLE;
 | 
				
			||||||
 | 
					    if (mHandover[burstTN][0])
 | 
				
			||||||
 | 
					      return RACH;
 | 
				
			||||||
    return TSC;
 | 
					    return TSC;
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case III:
 | 
					  case III:
 | 
				
			||||||
 | 
					    subch = tchh_subslot[burstFN % 26];
 | 
				
			||||||
 | 
					    if (mHandover[burstTN][subch])
 | 
				
			||||||
 | 
					      return RACH;
 | 
				
			||||||
    return TSC;
 | 
					    return TSC;
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
  case IV:
 | 
					  case IV:
 | 
				
			||||||
@@ -495,6 +519,8 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
 | 
				
			|||||||
      return RACH;
 | 
					      return RACH;
 | 
				
			||||||
    else if ((mod51 == 45) || (mod51 == 46))
 | 
					    else if ((mod51 == 45) || (mod51 == 46))
 | 
				
			||||||
      return RACH;
 | 
					      return RACH;
 | 
				
			||||||
 | 
					    else if (mHandover[burstTN][sdcch4_subslot[burstFN % 102]])
 | 
				
			||||||
 | 
					      return RACH;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      return TSC;
 | 
					      return TSC;
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
@@ -502,6 +528,8 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
 | 
				
			|||||||
  case VII:
 | 
					  case VII:
 | 
				
			||||||
    if ((burstFN % 51 <= 14) && (burstFN % 51 >= 12))
 | 
					    if ((burstFN % 51 <= 14) && (burstFN % 51 >= 12))
 | 
				
			||||||
      return IDLE;
 | 
					      return IDLE;
 | 
				
			||||||
 | 
					    else if (mHandover[burstTN][sdcch8_subslot[burstFN % 102]])
 | 
				
			||||||
 | 
					      return RACH;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      return TSC;
 | 
					      return TSC;
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
@@ -531,13 +559,13 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
 | 
				
			|||||||
 * Detect RACH synchronization sequence within a burst. No equalization
 | 
					 * Detect RACH synchronization sequence within a burst. No equalization
 | 
				
			||||||
 * is used or available on the RACH channel.
 | 
					 * is used or available on the RACH channel.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool Transceiver::detectRACH(TransceiverState *state,
 | 
					int Transceiver::detectRACH(TransceiverState *state,
 | 
				
			||||||
                            signalVector &burst,
 | 
					                            signalVector &burst,
 | 
				
			||||||
                            complex &, float &toa)
 | 
					                            complex &, float &toa)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  float threshold = 6.0;
 | 
					  float threshold = 6.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return detectRACHBurst(burst, threshold, mSPSRx, &, &toa);
 | 
					  return detectRACHBurst(burst, threshold, mSPSRx, amp, toa);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -545,12 +573,13 @@ bool Transceiver::detectRACH(TransceiverState *state,
 | 
				
			|||||||
 * state information and channel estimate if necessary. Equalization
 | 
					 * state information and channel estimate if necessary. Equalization
 | 
				
			||||||
 * is currently disabled.
 | 
					 * is currently disabled.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
 | 
					int Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
 | 
				
			||||||
                           complex &, float &toa, GSM::Time &time)
 | 
					                           complex &, float &toa, GSM::Time &time)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  int success;
 | 
				
			||||||
  int tn = time.TN();
 | 
					  int tn = time.TN();
 | 
				
			||||||
  float chanOffset, threshold = 5.0;
 | 
					  float chanOffset, threshold = 5.0;
 | 
				
			||||||
  bool noise, needDFE = false, estimateChan = false;
 | 
					  bool needDFE = false, estimateChan = false;
 | 
				
			||||||
  double elapsed = time - state->chanEstimateTime[tn];
 | 
					  double elapsed = time - state->chanEstimateTime[tn];
 | 
				
			||||||
  signalVector *chanResp;
 | 
					  signalVector *chanResp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -565,17 +594,18 @@ bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Detect normal burst midambles */
 | 
					  /* Detect normal burst midambles */
 | 
				
			||||||
  if (!analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, &,
 | 
					  success = analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, amp,
 | 
				
			||||||
                           &toa, mMaxExpectedDelay, estimateChan,
 | 
					                                toa, mMaxExpectedDelay, estimateChan,
 | 
				
			||||||
                           &chanResp, &chanOffset)) {
 | 
					                                &chanResp, &chanOffset);
 | 
				
			||||||
    return false;
 | 
					  if (success <= 0) {
 | 
				
			||||||
 | 
					    return success;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  noise = state->mNoiseLev;
 | 
					 | 
				
			||||||
  state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Set equalizer if unabled */
 | 
					  /* Set equalizer if unabled */
 | 
				
			||||||
  if (needDFE && estimateChan) {
 | 
					  if (needDFE && estimateChan) {
 | 
				
			||||||
 | 
					     float noise = state->mNoiseLev;
 | 
				
			||||||
 | 
					     state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     state->chanResponse[tn] = chanResp;
 | 
					     state->chanResponse[tn] = chanResp;
 | 
				
			||||||
     state->chanRespOffset[tn] = chanOffset;
 | 
					     state->chanRespOffset[tn] = chanOffset;
 | 
				
			||||||
     state->chanRespAmplitude[tn] = amp;
 | 
					     state->chanRespAmplitude[tn] = amp;
 | 
				
			||||||
@@ -588,7 +618,7 @@ bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
 | 
				
			|||||||
     state->chanEstimateTime[tn] = time;
 | 
					     state->chanEstimateTime[tn] = time;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return true;;
 | 
					  return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -611,20 +641,33 @@ SoftVector *Transceiver::demodulate(TransceiverState *state,
 | 
				
			|||||||
  return demodulateBurst(burst, mSPSRx, amp, toa);
 | 
					  return demodulateBurst(burst, mSPSRx, amp, toa);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void writeToFile(radioVector *radio_burst, size_t chan)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GSM::Time time = radio_burst->getTime();
 | 
				
			||||||
 | 
					  std::ostringstream fname;
 | 
				
			||||||
 | 
					  fname << chan << "_" << time.FN() << "_" << time.TN() << ".fc";
 | 
				
			||||||
 | 
					  std::ofstream outfile (fname.str().c_str(), std::ofstream::binary);
 | 
				
			||||||
 | 
					  outfile.write((char*)radio_burst->getVector()->begin(), radio_burst->getVector()->size() * 2 * sizeof(float));
 | 
				
			||||||
 | 
					  outfile.close();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Pull bursts from the FIFO and handle according to the slot
 | 
					 * Pull bursts from the FIFO and handle according to the slot
 | 
				
			||||||
 * and burst correlation type. Equalzation is currently disabled. 
 | 
					 * and burst correlation type. Equalzation is currently disabled. 
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
 | 
					SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
 | 
				
			||||||
                                         int &timingOffset, size_t chan)
 | 
					                                         double &timingOffset, double &noise,
 | 
				
			||||||
 | 
					                                         size_t chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  bool success, equalize = false;
 | 
					  int success;
 | 
				
			||||||
 | 
					  bool equalize = false;
 | 
				
			||||||
  complex amp;
 | 
					  complex amp;
 | 
				
			||||||
  float toa, pow, max = -1.0, avg = 0.0;
 | 
					  float toa, pow, max = -1.0, avg = 0.0;
 | 
				
			||||||
  int max_i = -1;
 | 
					  int max_i = -1;
 | 
				
			||||||
  signalVector *burst;
 | 
					  signalVector *burst;
 | 
				
			||||||
  SoftVector *bits = NULL;
 | 
					  SoftVector *bits = NULL;
 | 
				
			||||||
  TransceiverState *state = &mStates[chan];
 | 
					  TransceiverState *state = &mStates[chan];
 | 
				
			||||||
 | 
					  isRssiValid = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Blocking FIFO read */
 | 
					  /* Blocking FIFO read */
 | 
				
			||||||
  radioVector *radio_burst = mReceiveFIFO[chan]->read();
 | 
					  radioVector *radio_burst = mReceiveFIFO[chan]->read();
 | 
				
			||||||
@@ -635,7 +678,15 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
 | 
				
			|||||||
  GSM::Time time = radio_burst->getTime();
 | 
					  GSM::Time time = radio_burst->getTime();
 | 
				
			||||||
  CorrType type = expectedCorrType(time, chan);
 | 
					  CorrType type = expectedCorrType(time, chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((type == OFF) || (type == IDLE)) {
 | 
					  /* Debug: dump bursts to disk */
 | 
				
			||||||
 | 
					  /* bits 0-7  - chan 0 timeslots
 | 
				
			||||||
 | 
					   * bits 8-15 - chan 1 timeslots */
 | 
				
			||||||
 | 
					  if (mWriteBurstToDiskMask & ((1<<time.TN()) << (8*chan)))
 | 
				
			||||||
 | 
					    writeToFile(radio_burst, chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* No processing if the timeslot is off.
 | 
				
			||||||
 | 
					   * Not even power level or noise calculation. */
 | 
				
			||||||
 | 
					  if (type == OFF) {
 | 
				
			||||||
    delete radio_burst;
 | 
					    delete radio_burst;
 | 
				
			||||||
    return NULL;
 | 
					    return NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -659,7 +710,25 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
 | 
				
			|||||||
  /* Average noise on diversity paths and update global levels */
 | 
					  /* Average noise on diversity paths and update global levels */
 | 
				
			||||||
  burst = radio_burst->getVector(max_i);
 | 
					  burst = radio_burst->getVector(max_i);
 | 
				
			||||||
  avg = sqrt(avg / radio_burst->chans());
 | 
					  avg = sqrt(avg / radio_burst->chans());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  wTime = time;
 | 
				
			||||||
 | 
					  RSSI = 20.0 * log10(rxFullScale / avg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* RSSI estimation are valid */
 | 
				
			||||||
 | 
					  isRssiValid = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type == IDLE) {
 | 
				
			||||||
 | 
					    /* Update noise levels */
 | 
				
			||||||
 | 
					    state->mNoises.insert(avg);
 | 
				
			||||||
    state->mNoiseLev = state->mNoises.avg();
 | 
					    state->mNoiseLev = state->mNoises.avg();
 | 
				
			||||||
 | 
					    noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delete radio_burst;
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    /* Do not update noise levels */
 | 
				
			||||||
 | 
					    noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Detect normal or RACH bursts */
 | 
					  /* Detect normal or RACH bursts */
 | 
				
			||||||
  if (type == TSC)
 | 
					  if (type == TSC)
 | 
				
			||||||
@@ -667,33 +736,27 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
 | 
				
			|||||||
  else
 | 
					  else
 | 
				
			||||||
    success = detectRACH(state, *burst, amp, toa);
 | 
					    success = detectRACH(state, *burst, amp, toa);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Update noise average if no bust detected or alert on error */
 | 
					  /* Alert an error and exit */
 | 
				
			||||||
  if (success <= 0) {
 | 
					  if (success <= 0) {
 | 
				
			||||||
    if (!success) {
 | 
					    if (success == -SIGERR_CLIP) {
 | 
				
			||||||
      state->mNoises.insert(avg);
 | 
					      LOG(WARNING) << "Clipping detected on received RACH or Normal Burst";
 | 
				
			||||||
    } else if (success == -SIGERR_CLIP) {
 | 
					    } else if (success != SIGERR_NONE) {
 | 
				
			||||||
      LOG(ALERT) << "Clipping detected on RACH input";
 | 
					      LOG(WARNING) << "Unhandled RACH or Normal Burst detection error";
 | 
				
			||||||
    } else if (success < 0) {
 | 
					 | 
				
			||||||
      LOG(ALERT) << "Unhandled RACH error";
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    delete radio_burst;
 | 
					    delete radio_burst;
 | 
				
			||||||
    return NULL;
 | 
					    return NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  timingOffset = toa / mSPSRx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Demodulate and set output info */
 | 
					  /* Demodulate and set output info */
 | 
				
			||||||
  if (equalize && (type != TSC))
 | 
					  if (equalize && (type != TSC))
 | 
				
			||||||
    equalize = false;
 | 
					    equalize = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (avg - state->mNoiseLev > 0.0)
 | 
					 | 
				
			||||||
  bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
 | 
					  bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  wTime = time;
 | 
					 | 
				
			||||||
  RSSI = (int) floor(20.0 * log10(rxFullScale / avg));
 | 
					 | 
				
			||||||
  timingOffset = (int) round(toa * 256.0 / mSPSRx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  delete radio_burst;
 | 
					  delete radio_burst;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  return bits;
 | 
					  return bits;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -743,6 +806,24 @@ void Transceiver::driveControl(size_t chan)
 | 
				
			|||||||
      sprintf(response,"RSP POWERON 1");
 | 
					      sprintf(response,"RSP POWERON 1");
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      sprintf(response,"RSP POWERON 0");
 | 
					      sprintf(response,"RSP POWERON 0");
 | 
				
			||||||
 | 
					      for (int i = 0; i < 8; i++) {
 | 
				
			||||||
 | 
					        for (int j = 0; j < 8; j++)
 | 
				
			||||||
 | 
					          mHandover[i][j] = false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (strcmp(command,"HANDOVER")==0){
 | 
				
			||||||
 | 
					    int ts=0,ss=0;
 | 
				
			||||||
 | 
					    sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&ts,&ss);
 | 
				
			||||||
 | 
					    mHandover[ts][ss] = true;
 | 
				
			||||||
 | 
					    LOG(WARNING) << "HANDOVER RACH at timeslot " << ts << " subslot " << ss;
 | 
				
			||||||
 | 
					    sprintf(response,"RSP HANDOVER 0 %d %d",ts,ss);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (strcmp(command,"NOHANDOVER")==0){
 | 
				
			||||||
 | 
					    int ts=0,ss=0;
 | 
				
			||||||
 | 
					    sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&ts,&ss);
 | 
				
			||||||
 | 
					    mHandover[ts][ss] = false;
 | 
				
			||||||
 | 
					    LOG(WARNING) << "NOHANDOVER at timeslot " << ts << " subslot " << ss;
 | 
				
			||||||
 | 
					    sprintf(response,"RSP NOHANDOVER 0 %d %d",ts,ss);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else if (strcmp(command,"SETMAXDLY")==0) {
 | 
					  else if (strcmp(command,"SETMAXDLY")==0) {
 | 
				
			||||||
    //set expected maximum time-of-arrival
 | 
					    //set expected maximum time-of-arrival
 | 
				
			||||||
@@ -836,6 +917,14 @@ void Transceiver::driveControl(size_t chan)
 | 
				
			|||||||
    sprintf(response,"RSP SETSLOT 0 %d %d",timeslot,corrCode);
 | 
					    sprintf(response,"RSP SETSLOT 0 %d %d",timeslot,corrCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  else if (strcmp(command,"_SETBURSTTODISKMASK")==0) {
 | 
				
			||||||
 | 
					    // debug command! may change or disapear without notice
 | 
				
			||||||
 | 
					    // set a mask which bursts to dump to disk
 | 
				
			||||||
 | 
					    int mask;
 | 
				
			||||||
 | 
					    sscanf(buffer,"%3s %s %d",cmdcheck,command,&mask);
 | 
				
			||||||
 | 
					    mWriteBurstToDiskMask = mask;
 | 
				
			||||||
 | 
					    sprintf(response,"RSP _SETBURSTTODISKMASK 0 %d",mask);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    LOG(WARNING) << "bogus command " << command << " on control interface.";
 | 
					    LOG(WARNING) << "bogus command " << command << " on control interface.";
 | 
				
			||||||
    sprintf(response,"RSP ERR 1");
 | 
					    sprintf(response,"RSP ERR 1");
 | 
				
			||||||
@@ -892,27 +981,34 @@ void Transceiver::driveReceiveRadio()
 | 
				
			|||||||
void Transceiver::driveReceiveFIFO(size_t chan)
 | 
					void Transceiver::driveReceiveFIFO(size_t chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SoftVector *rxBurst = NULL;
 | 
					  SoftVector *rxBurst = NULL;
 | 
				
			||||||
  int RSSI;
 | 
					  double RSSI; // in dBFS
 | 
				
			||||||
  int TOA;  // in 1/256 of a symbol
 | 
					  double dBm;  // in dBm
 | 
				
			||||||
 | 
					  double TOA;  // in symbols
 | 
				
			||||||
 | 
					  int TOAint;  // in 1/256 symbols
 | 
				
			||||||
 | 
					  double noise; // noise level in dBFS
 | 
				
			||||||
  GSM::Time burstTime;
 | 
					  GSM::Time burstTime;
 | 
				
			||||||
 | 
					  bool isRssiValid; // are RSSI, noise and burstTime valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rxBurst = pullRadioVector(burstTime, RSSI, TOA, chan);
 | 
					  rxBurst = pullRadioVector(burstTime, RSSI, isRssiValid, TOA, noise, chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (rxBurst) { 
 | 
					  if (rxBurst) { 
 | 
				
			||||||
 | 
					    dBm = RSSI+rssiOffset;
 | 
				
			||||||
 | 
					    TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG(DEBUG) << "burst parameters: "
 | 
						LOG(DEBUG) << std::fixed << std::right
 | 
				
			||||||
      << " time: "   << burstTime
 | 
					      << " time: "   << burstTime
 | 
				
			||||||
	  << " RSSI: " << RSSI
 | 
						  << " RSSI: "   << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -dBm << "dBm"
 | 
				
			||||||
	  << " TOA: "  << TOA
 | 
						  << " noise: "  << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -(noise+rssiOffset) << "dBm"
 | 
				
			||||||
 | 
						  << " TOA: "    << std::setw(5) << std::setprecision(2) << TOA
 | 
				
			||||||
      << " bits: "   << *rxBurst;
 | 
					      << " bits: "   << *rxBurst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char burstString[gSlotLen+10];
 | 
					    char burstString[gSlotLen+10];
 | 
				
			||||||
    burstString[0] = burstTime.TN();
 | 
					    burstString[0] = burstTime.TN();
 | 
				
			||||||
    for (int i = 0; i < 4; i++)
 | 
					    for (int i = 0; i < 4; i++)
 | 
				
			||||||
      burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
 | 
					      burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
 | 
				
			||||||
    burstString[5] = RSSI;
 | 
					    burstString[5] = (int)dBm;
 | 
				
			||||||
    burstString[6] = (TOA >> 8) & 0x0ff;
 | 
					    burstString[6] = (TOAint >> 8) & 0x0ff;
 | 
				
			||||||
    burstString[7] = TOA & 0x0ff;
 | 
					    burstString[7] = TOAint & 0x0ff;
 | 
				
			||||||
    SoftVector::iterator burstItr = rxBurst->begin();
 | 
					    SoftVector::iterator burstItr = rxBurst->begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (unsigned int i = 0; i < gSlotLen; i++) {
 | 
					    for (unsigned int i = 0; i < gSlotLen; i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,7 +100,8 @@ public:
 | 
				
			|||||||
              const char *TRXAddress,
 | 
					              const char *TRXAddress,
 | 
				
			||||||
              size_t wSPS, size_t chans,
 | 
					              size_t wSPS, size_t chans,
 | 
				
			||||||
              GSM::Time wTransmitLatency,
 | 
					              GSM::Time wTransmitLatency,
 | 
				
			||||||
	      RadioInterface *wRadioInterface);
 | 
					              RadioInterface *wRadioInterface,
 | 
				
			||||||
 | 
					              double wRssiOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Destructor */
 | 
					  /** Destructor */
 | 
				
			||||||
  ~Transceiver();
 | 
					  ~Transceiver();
 | 
				
			||||||
@@ -181,6 +182,8 @@ private:
 | 
				
			|||||||
  double txFullScale;                     ///< full scale input to radio
 | 
					  double txFullScale;                     ///< full scale input to radio
 | 
				
			||||||
  double rxFullScale;                     ///< full scale output to radio
 | 
					  double rxFullScale;                     ///< full scale output to radio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double rssiOffset;                      ///< RSSI to dBm conversion offset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** modulate and add a burst to the transmit queue */
 | 
					  /** modulate and add a burst to the transmit queue */
 | 
				
			||||||
  void addRadioVector(size_t chan, BitVector &bits,
 | 
					  void addRadioVector(size_t chan, BitVector &bits,
 | 
				
			||||||
                      int RSSI, GSM::Time &wTime);
 | 
					                      int RSSI, GSM::Time &wTime);
 | 
				
			||||||
@@ -192,8 +195,9 @@ private:
 | 
				
			|||||||
  void pushRadioVector(GSM::Time &nowTime);
 | 
					  void pushRadioVector(GSM::Time &nowTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Pull and demodulate a burst from the receive FIFO */
 | 
					  /** Pull and demodulate a burst from the receive FIFO */
 | 
				
			||||||
  SoftVector *pullRadioVector(GSM::Time &wTime, int &RSSI,
 | 
					  SoftVector *pullRadioVector(GSM::Time &wTime, double &RSSI, bool &isRssiValid,
 | 
				
			||||||
                              int &timingOffset, size_t chan = 0);
 | 
					                              double &timingOffset, double &noise,
 | 
				
			||||||
 | 
					                              size_t chan = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Set modulus for specific timeslot */
 | 
					  /** Set modulus for specific timeslot */
 | 
				
			||||||
  void setModulus(size_t timeslot, size_t chan);
 | 
					  void setModulus(size_t timeslot, size_t chan);
 | 
				
			||||||
@@ -205,12 +209,12 @@ private:
 | 
				
			|||||||
  void writeClockInterface(void);
 | 
					  void writeClockInterface(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Detect RACH bursts */
 | 
					  /** Detect RACH bursts */
 | 
				
			||||||
  bool detectRACH(TransceiverState *state,
 | 
					  int detectRACH(TransceiverState *state,
 | 
				
			||||||
                 signalVector &burst,
 | 
					                 signalVector &burst,
 | 
				
			||||||
                 complex &, float &toa);
 | 
					                 complex &, float &toa);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Detect normal bursts */
 | 
					  /** Detect normal bursts */
 | 
				
			||||||
  bool detectTSC(TransceiverState *state,
 | 
					  int detectTSC(TransceiverState *state,
 | 
				
			||||||
                signalVector &burst,
 | 
					                signalVector &burst,
 | 
				
			||||||
                complex &, float &toa, GSM::Time &time);
 | 
					                complex &, float &toa, GSM::Time &time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -224,10 +228,12 @@ private:
 | 
				
			|||||||
  size_t mChans;
 | 
					  size_t mChans;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool mOn;	                           ///< flag to indicate that transceiver is powered on
 | 
					  bool mOn;	                           ///< flag to indicate that transceiver is powered on
 | 
				
			||||||
 | 
					  bool mHandover[8][8];                ///< expect handover to the timeslot/subslot
 | 
				
			||||||
  double mTxFreq;                      ///< the transmit frequency
 | 
					  double mTxFreq;                      ///< the transmit frequency
 | 
				
			||||||
  double mRxFreq;                      ///< the receive frequency
 | 
					  double mRxFreq;                      ///< the receive frequency
 | 
				
			||||||
  unsigned mTSC;                       ///< the midamble sequence code
 | 
					  unsigned mTSC;                       ///< the midamble sequence code
 | 
				
			||||||
  unsigned mMaxExpectedDelay;          ///< maximum expected time-of-arrival offset in GSM symbols
 | 
					  unsigned mMaxExpectedDelay;          ///< maximum expected time-of-arrival offset in GSM symbols
 | 
				
			||||||
 | 
					  unsigned mWriteBurstToDiskMask;      ///< debug: bitmask to indicate which timeslots to dump to disk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<TransceiverState> mStates;
 | 
					  std::vector<TransceiverState> mStates;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -210,8 +210,7 @@ uhd::time_spec_t convert_time(TIMESTAMP ticks, double rate)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
TIMESTAMP convert_time(uhd::time_spec_t ts, double rate)
 | 
					TIMESTAMP convert_time(uhd::time_spec_t ts, double rate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	TIMESTAMP ticks = ts.get_full_secs() * rate;
 | 
						return (TIMESTAMP)(ts.get_real_secs() * rate + 0.5);
 | 
				
			||||||
	return ts.get_tick_count(rate) + ticks;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -290,7 +289,7 @@ public:
 | 
				
			|||||||
	uhd_device(size_t sps, size_t chans, bool diversity, double offset);
 | 
						uhd_device(size_t sps, size_t chans, bool diversity, double offset);
 | 
				
			||||||
	~uhd_device();
 | 
						~uhd_device();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int open(const std::string &args, bool extref);
 | 
						int open(const std::string &args, bool extref, bool swap_channels);
 | 
				
			||||||
	bool start();
 | 
						bool start();
 | 
				
			||||||
	bool stop();
 | 
						bool stop();
 | 
				
			||||||
	bool restart();
 | 
						bool restart();
 | 
				
			||||||
@@ -473,18 +472,24 @@ void uhd_device::init_gains()
 | 
				
			|||||||
		tx_gain_min = range.start();
 | 
							tx_gain_min = range.start();
 | 
				
			||||||
		tx_gain_max = range.stop();
 | 
							tx_gain_max = range.stop();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						LOG(INFO) << "Supported Tx gain range [" << tx_gain_min << "; " << tx_gain_max << "]";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	range = usrp_dev->get_rx_gain_range();
 | 
						range = usrp_dev->get_rx_gain_range();
 | 
				
			||||||
	rx_gain_min = range.start();
 | 
						rx_gain_min = range.start();
 | 
				
			||||||
	rx_gain_max = range.stop();
 | 
						rx_gain_max = range.stop();
 | 
				
			||||||
 | 
						LOG(INFO) << "Supported Rx gain range [" << rx_gain_min << "; " << rx_gain_max << "]";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < tx_gains.size(); i++) {
 | 
						for (size_t i = 0; i < tx_gains.size(); i++) {
 | 
				
			||||||
		usrp_dev->set_tx_gain((tx_gain_min + tx_gain_max) / 2, i);
 | 
							double gain = (tx_gain_min + tx_gain_max) / 2;
 | 
				
			||||||
 | 
							LOG(INFO) << "Default setting Tx gain for channel " << i << " to " << gain;
 | 
				
			||||||
 | 
							usrp_dev->set_tx_gain(gain, i);
 | 
				
			||||||
		tx_gains[i] = usrp_dev->get_tx_gain(i);
 | 
							tx_gains[i] = usrp_dev->get_tx_gain(i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < rx_gains.size(); i++) {
 | 
						for (size_t i = 0; i < rx_gains.size(); i++) {
 | 
				
			||||||
		usrp_dev->set_rx_gain((rx_gain_min + rx_gain_max) / 2, i);
 | 
							double gain = (rx_gain_min + rx_gain_max) / 2;
 | 
				
			||||||
 | 
							LOG(INFO) << "Default setting Rx gain for channel " << i << " to " << gain;
 | 
				
			||||||
 | 
							usrp_dev->set_rx_gain(gain, i);
 | 
				
			||||||
		rx_gains[i] = usrp_dev->get_rx_gain(i);
 | 
							rx_gains[i] = usrp_dev->get_rx_gain(i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -582,7 +587,7 @@ double uhd_device::setTxGain(double db, size_t chan)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	tx_gains[chan] = usrp_dev->get_tx_gain(chan);
 | 
						tx_gains[chan] = usrp_dev->get_tx_gain(chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LOG(INFO) << "Set TX gain to " << tx_gains[chan] << "dB";
 | 
						LOG(INFO) << "Set TX gain to " << tx_gains[chan] << "dB (asked for " << db << "dB)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tx_gains[chan];
 | 
						return tx_gains[chan];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -597,7 +602,7 @@ double uhd_device::setRxGain(double db, size_t chan)
 | 
				
			|||||||
	usrp_dev->set_rx_gain(db, chan);
 | 
						usrp_dev->set_rx_gain(db, chan);
 | 
				
			||||||
	rx_gains[chan] = usrp_dev->get_rx_gain(chan);
 | 
						rx_gains[chan] = usrp_dev->get_rx_gain(chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LOG(INFO) << "Set RX gain to " << rx_gains[chan] << "dB";
 | 
						LOG(INFO) << "Set RX gain to " << rx_gains[chan] << "dB (asked for " << db << "dB)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rx_gains[chan];
 | 
						return rx_gains[chan];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -694,7 +699,7 @@ bool uhd_device::parse_dev_type()
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int uhd_device::open(const std::string &args, bool extref)
 | 
					int uhd_device::open(const std::string &args, bool extref, bool swap_channels)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// Find UHD devices
 | 
						// Find UHD devices
 | 
				
			||||||
	uhd::device_addr_t addr(args);
 | 
						uhd::device_addr_t addr(args);
 | 
				
			||||||
@@ -720,7 +725,7 @@ int uhd_device::open(const std::string &args, bool extref)
 | 
				
			|||||||
	// Verify and set channels
 | 
						// Verify and set channels
 | 
				
			||||||
	if ((dev_type == B210) && (chans == 2)) {
 | 
						if ((dev_type == B210) && (chans == 2)) {
 | 
				
			||||||
	} else if ((dev_type == UMTRX) && (chans == 2)) {
 | 
						} else if ((dev_type == UMTRX) && (chans == 2)) {
 | 
				
			||||||
		uhd::usrp::subdev_spec_t subdev_spec("A:0 B:0");
 | 
							uhd::usrp::subdev_spec_t subdev_spec(swap_channels?"B:0 A:0":"A:0 B:0");
 | 
				
			||||||
		usrp_dev->set_tx_subdev_spec(subdev_spec);
 | 
							usrp_dev->set_tx_subdev_spec(subdev_spec);
 | 
				
			||||||
		usrp_dev->set_rx_subdev_spec(subdev_spec);
 | 
							usrp_dev->set_rx_subdev_spec(subdev_spec);
 | 
				
			||||||
	} else if (chans != 1) {
 | 
						} else if (chans != 1) {
 | 
				
			||||||
@@ -1115,7 +1120,7 @@ uhd::tune_request_t uhd_device::select_freq(double freq, size_t chan, bool tx)
 | 
				
			|||||||
	uhd::tune_request_t treq(freq);
 | 
						uhd::tune_request_t treq(freq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dev_type == UMTRX) {
 | 
						if (dev_type == UMTRX) {
 | 
				
			||||||
		if (offset > 0.0)
 | 
							if (offset != 0.0)
 | 
				
			||||||
			return uhd::tune_request_t(freq, offset);
 | 
								return uhd::tune_request_t(freq, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Don't use DSP tuning, because LMS6002D PLL steps are small enough.
 | 
							// Don't use DSP tuning, because LMS6002D PLL steps are small enough.
 | 
				
			||||||
@@ -1126,6 +1131,7 @@ uhd::tune_request_t uhd_device::select_freq(double freq, size_t chan, bool tx)
 | 
				
			|||||||
		treq.rf_freq = freq;
 | 
							treq.rf_freq = freq;
 | 
				
			||||||
		treq.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
 | 
							treq.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL;
 | 
				
			||||||
		treq.dsp_freq = 0.0;
 | 
							treq.dsp_freq = 0.0;
 | 
				
			||||||
 | 
							return treq;
 | 
				
			||||||
	} else if (chans == 1) {
 | 
						} else if (chans == 1) {
 | 
				
			||||||
		if (offset == 0.0)
 | 
							if (offset == 0.0)
 | 
				
			||||||
			return treq;
 | 
								return treq;
 | 
				
			||||||
@@ -1430,6 +1436,19 @@ ssize_t smpl_buf::write(void *buf, size_t len, TIMESTAMP timestamp)
 | 
				
			|||||||
	if ((timestamp + len) <= time_end)
 | 
						if ((timestamp + len) <= time_end)
 | 
				
			||||||
		return ERROR_TIMESTAMP;
 | 
							return ERROR_TIMESTAMP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (timestamp < time_end) {
 | 
				
			||||||
 | 
							LOG(ERR) << "Overwriting old buffer data: timestamp="<<timestamp<<" time_end="<<time_end;
 | 
				
			||||||
 | 
							uhd::time_spec_t ts = convert_time(timestamp, clk_rt);
 | 
				
			||||||
 | 
							LOG(DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << convert_time(ts, clk_rt) << ") rate=" << clk_rt;
 | 
				
			||||||
 | 
							// Do not return error here, because it's a rounding error and is not fatal
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (timestamp > time_end && time_end != 0) {
 | 
				
			||||||
 | 
							LOG(ERR) << "Skipping buffer data: timestamp="<<timestamp<<" time_end="<<time_end;
 | 
				
			||||||
 | 
							uhd::time_spec_t ts = convert_time(timestamp, clk_rt);
 | 
				
			||||||
 | 
							LOG(DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << convert_time(ts, clk_rt) << ") rate=" << clk_rt;
 | 
				
			||||||
 | 
							// Do not return error here, because it's a rounding error and is not fatal
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Starting index
 | 
						// Starting index
 | 
				
			||||||
	size_t write_start = (data_start + (timestamp - time_start)) % buf_len;
 | 
						size_t write_start = (data_start + (timestamp - time_start)) % buf_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,7 +89,7 @@ USRPDevice::USRPDevice(size_t sps, size_t, bool)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int USRPDevice::open(const std::string &, bool)
 | 
					int USRPDevice::open(const std::string &, bool, bool)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  writeLock.unlock();
 | 
					  writeLock.unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -99,7 +99,7 @@ private:
 | 
				
			|||||||
  USRPDevice(size_t sps, size_t chans = 1, bool diversity = false);
 | 
					  USRPDevice(size_t sps, size_t chans = 1, bool diversity = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Instantiate the USRP */
 | 
					  /** Instantiate the USRP */
 | 
				
			||||||
  int open(const std::string &, bool);
 | 
					  int open(const std::string &, bool, bool);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Start the USRP */
 | 
					  /** Start the USRP */
 | 
				
			||||||
  bool start();
 | 
					  bool start();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,8 @@ struct trx_config {
 | 
				
			|||||||
	Transceiver::FillerType filler;
 | 
						Transceiver::FillerType filler;
 | 
				
			||||||
	bool diversity;
 | 
						bool diversity;
 | 
				
			||||||
	double offset;
 | 
						double offset;
 | 
				
			||||||
 | 
						double rssi_offset;
 | 
				
			||||||
 | 
						bool swap_channels;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConfigurationTable gConfig;
 | 
					ConfigurationTable gConfig;
 | 
				
			||||||
@@ -185,6 +187,8 @@ bool trx_setup_config(struct trx_config *config)
 | 
				
			|||||||
	ost << "   C0 Filler Table......... " << fillstr << std::endl;
 | 
						ost << "   C0 Filler Table......... " << fillstr << std::endl;
 | 
				
			||||||
	ost << "   Diversity............... " << divstr << std::endl;
 | 
						ost << "   Diversity............... " << divstr << std::endl;
 | 
				
			||||||
	ost << "   Tuning offset........... " << config->offset << std::endl;
 | 
						ost << "   Tuning offset........... " << config->offset << std::endl;
 | 
				
			||||||
 | 
						ost << "   RSSI to dBm offset...... " << config->rssi_offset << std::endl;
 | 
				
			||||||
 | 
						ost << "   Swap channels........... " << config->swap_channels << std::endl;
 | 
				
			||||||
	std::cout << ost << std::endl;
 | 
						std::cout << ost << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
@@ -240,7 +244,7 @@ Transceiver *makeTransceiver(struct trx_config *config, RadioInterface *radio)
 | 
				
			|||||||
	VectorFIFO *fifo;
 | 
						VectorFIFO *fifo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	trx = new Transceiver(config->port, config->addr.c_str(), config->sps,
 | 
						trx = new Transceiver(config->port, config->addr.c_str(), config->sps,
 | 
				
			||||||
			      config->chans, GSM::Time(3,0), radio);
 | 
							config->chans, GSM::Time(3,0), radio, config->rssi_offset);
 | 
				
			||||||
	if (!trx->init(config->filler, config->rtsc)) {
 | 
						if (!trx->init(config->filler, config->rtsc)) {
 | 
				
			||||||
		LOG(ALERT) << "Failed to initialize transceiver";
 | 
							LOG(ALERT) << "Failed to initialize transceiver";
 | 
				
			||||||
		delete trx;
 | 
							delete trx;
 | 
				
			||||||
@@ -292,7 +296,9 @@ static void print_help()
 | 
				
			|||||||
		"  -c    Number of ARFCN channels (default=1)\n"
 | 
							"  -c    Number of ARFCN channels (default=1)\n"
 | 
				
			||||||
		"  -f    Enable C0 filler table\n"
 | 
							"  -f    Enable C0 filler table\n"
 | 
				
			||||||
		"  -o    Set baseband frequency offset (default=auto)\n"
 | 
							"  -o    Set baseband frequency offset (default=auto)\n"
 | 
				
			||||||
		"  -r    Random burst test mode with TSC\n",
 | 
							"  -r    Random burst test mode with TSC\n"
 | 
				
			||||||
 | 
							"  -R    RSSI to dBm offset in dB (default=0)\n"
 | 
				
			||||||
 | 
							"  -S    Swap channels (UmTRX only)\n",
 | 
				
			||||||
		"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
 | 
							"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -308,8 +314,10 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
 | 
				
			|||||||
	config->filler = Transceiver::FILLER_ZERO;
 | 
						config->filler = Transceiver::FILLER_ZERO;
 | 
				
			||||||
	config->diversity = false;
 | 
						config->diversity = false;
 | 
				
			||||||
	config->offset = 0.0;
 | 
						config->offset = 0.0;
 | 
				
			||||||
 | 
						config->rssi_offset = 0.0;
 | 
				
			||||||
 | 
						config->swap_channels = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:")) != -1) {
 | 
						while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:R:S")) != -1) {
 | 
				
			||||||
		switch (option) {
 | 
							switch (option) {
 | 
				
			||||||
		case 'h':
 | 
							case 'h':
 | 
				
			||||||
			print_help();
 | 
								print_help();
 | 
				
			||||||
@@ -349,6 +357,12 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
 | 
				
			|||||||
			config->rtsc = atoi(optarg);
 | 
								config->rtsc = atoi(optarg);
 | 
				
			||||||
			config->filler = Transceiver::FILLER_RAND;
 | 
								config->filler = Transceiver::FILLER_RAND;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case 'R':
 | 
				
			||||||
 | 
								config->rssi_offset = atof(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'S':
 | 
				
			||||||
 | 
								config->swap_channels = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			print_help();
 | 
								print_help();
 | 
				
			||||||
			exit(0);
 | 
								exit(0);
 | 
				
			||||||
@@ -393,7 +407,7 @@ int main(int argc, char *argv[])
 | 
				
			|||||||
	/* Create the low level device object */
 | 
						/* Create the low level device object */
 | 
				
			||||||
	usrp = RadioDevice::make(config.sps, config.chans,
 | 
						usrp = RadioDevice::make(config.sps, config.chans,
 | 
				
			||||||
				 config.diversity, config.offset);
 | 
									 config.diversity, config.offset);
 | 
				
			||||||
	type = usrp->open(config.dev_args, config.extref);
 | 
						type = usrp->open(config.dev_args, config.extref, config.swap_channels);
 | 
				
			||||||
	if (type < 0) {
 | 
						if (type < 0) {
 | 
				
			||||||
		LOG(ALERT) << "Failed to create radio device" << std::endl;
 | 
							LOG(ALERT) << "Failed to create radio device" << std::endl;
 | 
				
			||||||
		goto shutdown;
 | 
							goto shutdown;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ class RadioDevice {
 | 
				
			|||||||
                           bool diversity = false, double offset = 0.0);
 | 
					                           bool diversity = false, double offset = 0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Initialize the USRP */
 | 
					  /** Initialize the USRP */
 | 
				
			||||||
  virtual int open(const std::string &args = "", bool extref = false)=0;
 | 
					  virtual int open(const std::string &args = "", bool extref = false, bool swap_channels = false)=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual ~RadioDevice() { }
 | 
					  virtual ~RadioDevice() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "sigProcLib.h"
 | 
					#include "sigProcLib.h"
 | 
				
			||||||
#include "GSMCommon.h"
 | 
					#include "GSMCommon.h"
 | 
				
			||||||
 | 
					#include "Logger.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#include "convolve.h"
 | 
					#include "convolve.h"
 | 
				
			||||||
@@ -1284,12 +1285,12 @@ static float computePeakRatio(signalVector *corr,
 | 
				
			|||||||
  complex *peak;
 | 
					  complex *peak;
 | 
				
			||||||
  float rms, avg = 0.0;
 | 
					  float rms, avg = 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  peak = corr->begin() + (int) rint(toa);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Check for bogus results */
 | 
					  /* Check for bogus results */
 | 
				
			||||||
  if ((toa < 0.0) || (toa > corr->size()))
 | 
					  if ((toa < 0.0) || (toa > corr->size()))
 | 
				
			||||||
    return 0.0;
 | 
					    return 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  peak = corr->begin() + (int) rint(toa);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 2 * sps; i <= 5 * sps; i++) {
 | 
					  for (int i = 2 * sps; i <= 5 * sps; i++) {
 | 
				
			||||||
    if (peak - i >= corr->begin()) {
 | 
					    if (peak - i >= corr->begin()) {
 | 
				
			||||||
      avg += (peak - i)->norm2();
 | 
					      avg += (peak - i)->norm2();
 | 
				
			||||||
@@ -1372,18 +1373,74 @@ static int detectBurst(signalVector &burst,
 | 
				
			|||||||
  return 1;
 | 
					  return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int detectClipping(signalVector &burst, float thresh)
 | 
					static float maxAmplitude(signalVector &burst)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    float max = 0.0;
 | 
				
			||||||
    for (size_t i = 0; i < burst.size(); i++) {
 | 
					    for (size_t i = 0; i < burst.size(); i++) {
 | 
				
			||||||
		if (fabs(burst[i].real()) > thresh)
 | 
					        if (fabs(burst[i].real()) > max)
 | 
				
			||||||
			return 1;
 | 
					            max = fabs(burst[i].real());
 | 
				
			||||||
		if (fabs(burst[i].imag()) > thresh)
 | 
					        if (fabs(burst[i].imag()) > max)
 | 
				
			||||||
			return 1;
 | 
					            max = fabs(burst[i].imag());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
					    return max;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * RACH/Normal burst detection with clipping detection
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Correlation window parameters:
 | 
				
			||||||
 | 
					 *   target: Tail bits + burst length
 | 
				
			||||||
 | 
					 *   head: Search symbols before target
 | 
				
			||||||
 | 
					 *   tail: Search symbols after target
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int detectGeneralBurst(signalVector &rxBurst,
 | 
				
			||||||
 | 
					                       float thresh,
 | 
				
			||||||
 | 
					                       int sps,
 | 
				
			||||||
 | 
					                       complex &,
 | 
				
			||||||
 | 
					                       float &toa,
 | 
				
			||||||
 | 
					                       int target, int head, int tail,
 | 
				
			||||||
 | 
					                       CorrelationSequence *sync)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int rc, start, len;
 | 
				
			||||||
 | 
					  bool clipping = false;
 | 
				
			||||||
 | 
					  signalVector *corr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ((sps != 1) && (sps != 4))
 | 
				
			||||||
 | 
					    return -SIGERR_UNSUPPORTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Detect potential clipping
 | 
				
			||||||
 | 
					  // We still may be able to demod the burst, so we'll give it a try
 | 
				
			||||||
 | 
					  // and only report clipping if we can't demod.
 | 
				
			||||||
 | 
					  float maxAmpl = maxAmplitude(rxBurst);
 | 
				
			||||||
 | 
					  if (maxAmpl > CLIP_THRESH) {
 | 
				
			||||||
 | 
					    LOG(DEBUG) << "max burst amplitude: " << maxAmpl << " is above the clipping threshold: " << CLIP_THRESH << std::endl;
 | 
				
			||||||
 | 
					    clipping = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  start = (target - head) * sps - 1;
 | 
				
			||||||
 | 
					  len = (head + tail) * sps;
 | 
				
			||||||
 | 
					  corr = new signalVector(len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  rc = detectBurst(rxBurst, *corr, sync,
 | 
				
			||||||
 | 
					                   thresh, sps, &, &toa, start, len);
 | 
				
			||||||
 | 
					  delete corr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (rc < 0) {
 | 
				
			||||||
 | 
					    return -SIGERR_INTERNAL;
 | 
				
			||||||
 | 
					  } else if (!rc) {
 | 
				
			||||||
 | 
					    amp = 0.0f;
 | 
				
			||||||
 | 
					    toa = 0.0f;
 | 
				
			||||||
 | 
					    return clipping?-SIGERR_CLIP:SIGERR_NONE;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Subtract forward search bits from delay */
 | 
				
			||||||
 | 
					  toa -= head * sps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 
 | 
					/* 
 | 
				
			||||||
 * RACH burst detection
 | 
					 * RACH burst detection
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -1395,51 +1452,21 @@ static int detectClipping(signalVector &burst, float thresh)
 | 
				
			|||||||
int detectRACHBurst(signalVector &rxBurst,
 | 
					int detectRACHBurst(signalVector &rxBurst,
 | 
				
			||||||
            float thresh,
 | 
					            float thresh,
 | 
				
			||||||
            int sps,
 | 
					            int sps,
 | 
				
			||||||
		    complex *amp,
 | 
					            complex &,
 | 
				
			||||||
		    float *toa)
 | 
					            float &toa)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int rc, start, target, head, tail, len;
 | 
					  int rc, target, head, tail;
 | 
				
			||||||
  float _toa;
 | 
					 | 
				
			||||||
  complex _amp;
 | 
					 | 
				
			||||||
  signalVector *corr;
 | 
					 | 
				
			||||||
  CorrelationSequence *sync;
 | 
					  CorrelationSequence *sync;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((sps != 1) && (sps != 4))
 | 
					 | 
				
			||||||
    return -SIGERR_UNSUPPORTED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (detectClipping(rxBurst, CLIP_THRESH))
 | 
					 | 
				
			||||||
    return -SIGERR_CLIP;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  target = 8 + 40;
 | 
					  target = 8 + 40;
 | 
				
			||||||
  head = 4;
 | 
					  head = 4;
 | 
				
			||||||
  tail = 10;
 | 
					  tail = 10;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  start = (target - head) * sps - 1;
 | 
					 | 
				
			||||||
  len = (head + tail) * sps;
 | 
					 | 
				
			||||||
  sync = gRACHSequence;
 | 
					  sync = gRACHSequence;
 | 
				
			||||||
  corr = new signalVector(len);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rc = detectBurst(rxBurst, *corr, sync,
 | 
					  rc = detectGeneralBurst(rxBurst, thresh, sps, amp, toa,
 | 
				
			||||||
                   thresh, sps, &_amp, &_toa, start, len);
 | 
					                          target, head, tail, sync);
 | 
				
			||||||
  delete corr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (rc < 0) {
 | 
					  return rc;
 | 
				
			||||||
    return -SIGERR_INTERNAL;
 | 
					 | 
				
			||||||
  } else if (!rc) {
 | 
					 | 
				
			||||||
    if (amp)
 | 
					 | 
				
			||||||
      *amp = 0.0f;
 | 
					 | 
				
			||||||
    if (toa)
 | 
					 | 
				
			||||||
      *toa = 0.0f;
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Subtract forward search bits from delay */
 | 
					 | 
				
			||||||
  if (toa)
 | 
					 | 
				
			||||||
    *toa = _toa - head * sps;
 | 
					 | 
				
			||||||
  if (amp)
 | 
					 | 
				
			||||||
    *amp = _amp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return 1;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 
 | 
					/* 
 | 
				
			||||||
@@ -1451,60 +1478,32 @@ int detectRACHBurst(signalVector &rxBurst,
 | 
				
			|||||||
 *   tail: Search 4 symbols + maximum expected delay
 | 
					 *   tail: Search 4 symbols + maximum expected delay
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
 | 
					int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
 | 
				
			||||||
                        int sps, complex *amp, float *toa, unsigned max_toa,
 | 
					                        int sps, complex &, float &toa, unsigned max_toa,
 | 
				
			||||||
                        bool chan_req, signalVector **chan, float *chan_offset)
 | 
					                        bool chan_req, signalVector **chan, float *chan_offset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int rc, start, target, head, tail, len;
 | 
					  int rc, target, head, tail;
 | 
				
			||||||
  complex _amp;
 | 
					 | 
				
			||||||
  float _toa;
 | 
					 | 
				
			||||||
  signalVector *corr;
 | 
					 | 
				
			||||||
  CorrelationSequence *sync;
 | 
					  CorrelationSequence *sync;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 4)))
 | 
					  if ((tsc < 0) || (tsc > 7))
 | 
				
			||||||
    return -SIGERR_UNSUPPORTED;
 | 
					    return -SIGERR_UNSUPPORTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (detectClipping(rxBurst, CLIP_THRESH))
 | 
					 | 
				
			||||||
    return -SIGERR_CLIP;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  target = 3 + 58 + 16 + 5;
 | 
					  target = 3 + 58 + 16 + 5;
 | 
				
			||||||
  head = 4;
 | 
					  head = 4;
 | 
				
			||||||
  tail = 4 + max_toa;
 | 
					  tail = 4 + max_toa;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  start = (target - head) * sps - 1;
 | 
					 | 
				
			||||||
  len = (head + tail) * sps;
 | 
					 | 
				
			||||||
  sync = gMidambles[tsc];
 | 
					  sync = gMidambles[tsc];
 | 
				
			||||||
  corr = new signalVector(len);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rc = detectBurst(rxBurst, *corr, sync,
 | 
					  rc = detectGeneralBurst(rxBurst, thresh, sps, amp, toa,
 | 
				
			||||||
                   thresh, sps, &_amp, &_toa, start, len);
 | 
					                          target, head, tail, sync);
 | 
				
			||||||
  delete corr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (rc < 0) {
 | 
					 | 
				
			||||||
    return -SIGERR_INTERNAL;
 | 
					 | 
				
			||||||
  } else if (!rc) {
 | 
					 | 
				
			||||||
    if (amp)
 | 
					 | 
				
			||||||
      *amp = 0.0f;
 | 
					 | 
				
			||||||
    if (toa)
 | 
					 | 
				
			||||||
      *toa = 0.0f;
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Subtract forward search bits from delay */
 | 
					 | 
				
			||||||
  _toa -= head * sps;
 | 
					 | 
				
			||||||
  if (toa)
 | 
					 | 
				
			||||||
    *toa = _toa;
 | 
					 | 
				
			||||||
  if (amp)
 | 
					 | 
				
			||||||
    *amp = _amp;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Equalization not currently supported */
 | 
					  /* Equalization not currently supported */
 | 
				
			||||||
  if (chan_req) {
 | 
					  if (rc > 0 && chan_req) {
 | 
				
			||||||
    *chan = new signalVector(6 * sps);
 | 
					    *chan = new signalVector(6 * sps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (chan_offset)
 | 
					    if (chan_offset)
 | 
				
			||||||
      *chan_offset = 0.0;
 | 
					      *chan_offset = 0.0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 1;
 | 
					  return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signalVector *decimateVector(signalVector &wVector, size_t factor)
 | 
					signalVector *decimateVector(signalVector &wVector, size_t factor)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -192,8 +192,8 @@ bool energyDetect(signalVector &rxBurst,
 | 
				
			|||||||
int detectRACHBurst(signalVector &rxBurst,
 | 
					int detectRACHBurst(signalVector &rxBurst,
 | 
				
			||||||
                    float detectThreshold,
 | 
					                    float detectThreshold,
 | 
				
			||||||
                    int sps,
 | 
					                    int sps,
 | 
				
			||||||
                    complex *amplitude,
 | 
					                    complex &litude,
 | 
				
			||||||
                    float* TOA);
 | 
					                    float &TOA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
        Normal burst correlator, detector, channel estimator.
 | 
					        Normal burst correlator, detector, channel estimator.
 | 
				
			||||||
@@ -213,8 +213,8 @@ int analyzeTrafficBurst(signalVector &rxBurst,
 | 
				
			|||||||
                        unsigned TSC,
 | 
					                        unsigned TSC,
 | 
				
			||||||
                        float detectThreshold,
 | 
					                        float detectThreshold,
 | 
				
			||||||
                        int sps,
 | 
					                        int sps,
 | 
				
			||||||
			complex *amplitude,
 | 
					                        complex &litude,
 | 
				
			||||||
			float *TOA,
 | 
					                        float &TOA,
 | 
				
			||||||
                        unsigned maxTOA,
 | 
					                        unsigned maxTOA,
 | 
				
			||||||
                        bool requestChannel = false,
 | 
					                        bool requestChannel = false,
 | 
				
			||||||
                        signalVector** channelResponse = NULL,
 | 
					                        signalVector** channelResponse = NULL,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
if !ARCH_ARM
 | 
					if !ARCH_ARM
 | 
				
			||||||
AM_CFLAGS = -Wall -std=gnu99 -march=native -I../common
 | 
					AM_CFLAGS = -Wall -std=gnu99 -I../common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
noinst_LTLIBRARIES = libarch.la
 | 
					noinst_LTLIBRARIES = libarch.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					osmo-trx (0.1.9~1) trusty; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * minor debian changes
 | 
				
			||||||
 | 
					  * correct atom cross-compilation
 | 
				
			||||||
 | 
					  * corrected build-time and run-time dependencies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Kirill Zakharenko <earwin@gmail.com>  Thu, 23 Jul 2015 00:01:07 +0000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-trx (0.1.9) trusty; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Ask Ivan, really
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Kirill Zakharenko <earwin@gmail.com>  Thu, 16 Jul 2015 12:13:46 +0000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					osmo-trx (0.1.8) precise; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     * Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Ivan Klyuchnikov <Ivan.Kluchnikov@fairwaves.ru>  Sun, 9 Mar 2014 14:10:10 +0400
 | 
				
			||||||
							
								
								
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					9
 | 
				
			||||||
							
								
								
									
										24
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					Source: osmo-trx
 | 
				
			||||||
 | 
					Maintainer: Ivan Klyuchnikov <ivan.kluchnikov@fairwaves.ru>
 | 
				
			||||||
 | 
					Section: net
 | 
				
			||||||
 | 
					Priority: optional
 | 
				
			||||||
 | 
					Standards-Version: 3.9.3
 | 
				
			||||||
 | 
					Build-Depends: debhelper (>= 9), autotools-dev, libdbd-sqlite3, pkg-config, dh-autoreconf, libuhd-dev, libusb-1.0-0-dev, libboost-all-dev, hardening-wrapper
 | 
				
			||||||
 | 
					Homepage: http://openbsc.osmocom.org/trac/wiki/OsmoTRX
 | 
				
			||||||
 | 
					Vcs-Git: git://git.osmocom.org/osmo-trx
 | 
				
			||||||
 | 
					Vcs-Browser: http://cgit.osmocom.org/osmo-trx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package: osmo-trx
 | 
				
			||||||
 | 
					Architecture: any
 | 
				
			||||||
 | 
					Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
 | 
				
			||||||
 | 
					Description: OsmoTRX is a software-defined radio transceiver that implements the Layer 1 physical layer of a BTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package: osmo-trx-dbg
 | 
				
			||||||
 | 
					Architecture: any
 | 
				
			||||||
 | 
					Section: debug
 | 
				
			||||||
 | 
					Priority: extra
 | 
				
			||||||
 | 
					Depends: osmo-trx (= ${binary:Version}), ${misc:Depends}
 | 
				
			||||||
 | 
					Description: Debug symbols for the osmo-trx
 | 
				
			||||||
 | 
					 Make debugging possible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										25
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					The Debian packaging is:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2014 Max <max.suraev@fairwaves.ru>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It was downloaded from:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    git://git.osmocom.org/osmo-trx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Upstream Authors:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Thomas Tsou <tom@tsou.cc>
 | 
				
			||||||
 | 
					    David A. Burgess <dburgess@kestrelsp.com>
 | 
				
			||||||
 | 
					    Harvind S. Samra <hssamra@kestrelsp.com>
 | 
				
			||||||
 | 
					    Raffi Sevlian <raffisev@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     Copyright (C) 2012-2013 Thomas Tsou <tom@tsou.cc>
 | 
				
			||||||
 | 
					     Copyright (C) 2011 Range Networks, Inc.
 | 
				
			||||||
 | 
					     Copyright (C) 2008-2011 Free Software Foundation, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					License:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GNU Affero General Public License, Version 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								debian/osmo-trx.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/osmo-trx.install
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					/usr/bin/osmo-trx
 | 
				
			||||||
							
								
								
									
										15
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/make -f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEB_BUILD_HARDENING=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%:
 | 
				
			||||||
 | 
						dh $@ --with autoreconf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					override_dh_auto_configure:
 | 
				
			||||||
 | 
						dh_auto_configure -- --without-sse CFLAGS="-DHAVE_SSE3 -march=atom -mtune=atom -O2" CXXFLAGS="-DHAVE_SSE3 -march=atom -mtune=atom -O2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					override_dh_shlibdeps:
 | 
				
			||||||
 | 
						dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					override_dh_strip:
 | 
				
			||||||
 | 
						dh_strip --dbg-package=osmo-trx-dbg
 | 
				
			||||||
							
								
								
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					3.0 (native)
 | 
				
			||||||
							
								
								
									
										3
									
								
								utils/clockdump.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								utils/clockdump.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					sudo tcpdump -i lo0 -A udp port 5700
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user