Changeset 3689
- Timestamp:
- 05/30/2012 07:05:17 PM (13 months ago)
- Location:
- openbts/trunk/TransceiverRAD1
- Files:
-
- 8 modified
-
RAD1Device.h (modified) (3 diffs)
-
Transceiver.cpp (modified) (29 diffs)
-
Transceiver.h (modified) (12 diffs)
-
radioInterface.cpp (modified) (4 diffs)
-
radioInterface.h (modified) (3 diffs)
-
rnrad1Core.cpp (modified) (1 diff)
-
runTransceiver.cpp (modified) (1 diff)
-
sigProcLib.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
openbts/trunk/TransceiverRAD1/RAD1Device.h
r2242 r3689 125 125 static const unsigned TEST = 0; // bit 19 126 126 static const unsigned LDP = 1; // bit 18 127 static const unsigned ABP = 0; // bit 17,163ns127 static const unsigned ABP = 2; // bit 17,16 6ns, 0 = 3ns 128 128 129 129 // N-Register Common Values … … 132 132 // Control Register Common Values 133 133 static const unsigned PD = 0; // bits 21,20 Normal operation 134 static const unsigned PL = 2; // bits 13,12 7.5mA, -6dbm134 static const unsigned PL = 1; // bits 13,12 7.5mA, -6dbm 135 135 static const unsigned MTLD = 1; // bit 11 enabled 136 136 static const unsigned CPG = 0; // bit 10 CP setting 1 … … 139 139 static const unsigned MUXOUT = 1;// bits 7:5 Digital Lock Detect 140 140 static const unsigned CR = 0; // bit 4 Normal 141 static const unsigned PC = 2; // bits 3,2 Core power 15mA141 static const unsigned PC = 0; // bits 3,2 Core power 15mA 142 142 143 143 // ATR register value -
openbts/trunk/TransceiverRAD1/Transceiver.cpp
r3126 r3689 40 40 int wSamplesPerSymbol, 41 41 GSM::Time wTransmitLatency, 42 RadioInterface *wRadioInterface) 43 :mDataSocket(wBasePort+2,TRXAddress,wBasePort+102), 44 mControlSocket(wBasePort+1,TRXAddress,wBasePort+101), 45 mClockSocket(wBasePort,TRXAddress,wBasePort+100) 42 RadioInterface *wRadioInterface, 43 unsigned int wNumARFCNs, 44 unsigned int wOversamplingRate, 45 bool wLoadTest) 46 :mClockSocket(wBasePort,TRXAddress,wBasePort+100) 46 47 { 47 48 //GSM::Time startTime(0,0); 48 49 //GSM::Time startTime(gHyperframe/2 - 4*216*60,0); 49 GSM::Time startTime(random() % gHyperframe,0); 50 51 mFIFOServiceLoopThread = new Thread(32768); ///< thread to push bursts into transmit FIFO 52 mControlServiceLoopThread = new Thread(32768); ///< thread to process control messages from GSM core 53 mTransmitPriorityQueueServiceLoopThread = new Thread(32768);///< thread to process transmit bursts from GSM core 54 50 GSM::Time startTime = mStartTime = GSM::Time(random() % gHyperframe,0); 51 52 mFIFOServiceLoopThread = new Thread(2*32768); ///< thread to push bursts into transmit FIFO 53 mRFIFOServiceLoopThread = new Thread(4*32768); 54 for (int j = 0; j< wNumARFCNs; j++) { 55 mControlServiceLoopThread[j] = new Thread(32768); 56 mTransmitPriorityQueueServiceLoopThread[j] = new Thread(32768); 57 if (wNumARFCNs > 1) mDemodServiceLoopThread[j] = new Thread(32768); 58 mDemodFIFO[j] = new VectorFIFO; 59 mDataSocket[j] = new UDPSocket(wBasePort+2*(j+1),TRXAddress,wBasePort+100+2*(j+1)); 60 mControlSocket[j] = new UDPSocket(wBasePort+2*j+1,TRXAddress,wBasePort+100+2*j+1); 61 } 55 62 56 63 mSamplesPerSymbol = wSamplesPerSymbol; … … 61 68 mLatencyUpdateTime = startTime; 62 69 mRadioInterface->getClock()->set(startTime); 63 mMaxExpectedDelay = 0; 70 mMaxExpectedDelay = 1; 71 72 mNumARFCNs = wNumARFCNs; 73 mOversamplingRate = wOversamplingRate; 74 mLoadTest = wLoadTest; 75 76 LOG(INFO) << "running " << mNumARFCNs << " ARFCNs"; 64 77 65 78 // generate pulse and setup up signal processing library … … 77 90 mSamplesPerSymbol); 78 91 scaleVector(*modBurst,txFullScale); 79 fillerModulus[i] =26;92 fillerModulus[i] = 26; 80 93 for (int j = 0; j < 102; j++) { 81 94 fillerTable[j][i] = new signalVector(*modBurst); 82 95 } 83 96 delete modBurst; 84 mChanType[i] = NONE; 85 channelResponse[i] = NULL; 86 DFEForward[i] = NULL; 87 DFEFeedback[i] = NULL; 88 channelEstimateTime[i] = startTime; 97 for (int j = 0; j < mNumARFCNs; j++) { 98 mChanType[j][i] = NONE; 99 } 100 } 101 102 mFreqOffset = 0.0; 103 mMultipleARFCN = (mNumARFCNs > 1); 104 if (mMultipleARFCN) { 105 //mOversamplingRate = mNumARFCNs/2 + mNumARFCNs; 106 //mOversamplingRate = 15; //mOversamplingRate*4; 107 //if (mOversamplingRate % 2) mOversamplingRate++; 108 double beaconFreq = -1.0*(mNumARFCNs-1)*200e3; 109 for (int j = 0; j < mNumARFCNs; j++) { 110 frequencyShifter[j] = new signalVector(157*mOversamplingRate); 111 frequencyShifter[j]->fill(complex(1.0,0.0)); 112 frequencyShifter[j]->isRealOnly(false); 113 frequencyShift(frequencyShifter[j],frequencyShifter[j],2.0*M_PI*(beaconFreq+j*400e3)/(1625.0e3/6.0*mOversamplingRate)); 114 } 115 116 int filtLen = 6*mOversamplingRate; 117 decimationFilter = createLPF(0.5/mOversamplingRate,filtLen,1); 118 interpolationFilter = createLPF(0.5/mOversamplingRate,filtLen,1); 119 scaleVector(*interpolationFilter,mOversamplingRate); 120 mFreqOffset = -beaconFreq; 121 mRadioInterface->setSamplesPerSymbol(SAMPSPERSYM*mOversamplingRate); 122 123 // refill filler table 124 for (int i = 0; i < 8; i++) { 125 signalVector* modBurst = modulateBurst(gDummyBurst,*gsmPulse, 126 8 + (i % 4 == 0), 127 mSamplesPerSymbol); 128 scaleVector(*modBurst,txFullScale/mNumARFCNs); 129 signalVector *interpVec = polyphaseResampleVector(*modBurst,mOversamplingRate,1,interpolationFilter); 130 //signalVector *interpVec = new signalVector(modBurst->size()*mOversamplingRate); 131 //interpVec->fill(txFullScale); 132 multVector(*interpVec,*frequencyShifter[0]); 133 for (int j = 0; j < 102; j++) { 134 delete fillerTable[j][i]; 135 fillerTable[j][i] = new signalVector(*interpVec); 136 } 137 delete modBurst; 138 delete interpVec; 139 } 89 140 } 90 141 … … 93 144 mRxFreq = 0.0; 94 145 mPower = -10; 95 mEnergyThreshold = 5.0; // based on empirical data 96 prevFalseDetectionTime = startTime; 146 147 mControlLock.unlock(); 148 mTransmitPriorityQueueLock.unlock(); 149 97 150 } 98 151 … … 107 160 void Transceiver::addRadioVector(BitVector &burst, 108 161 int RSSI, 109 GSM::Time &wTime) 162 GSM::Time &wTime, 163 int ARFCN) 110 164 { 111 165 // modulate and stick into queue … … 113 167 8 + (wTime.TN() % 4 == 0), 114 168 mSamplesPerSymbol); 115 scaleVector(*modBurst,txFullScale * pow(10,-RSSI/10)); 116 radioVector *newVec = new radioVector(*modBurst,wTime); 169 /*complex rScale = complex(2*M_PI*((float) rand()/(float) RAND_MAX),(2*M_PI*((float) rand()/(float) RAND_MAX))); 170 rScale = rScale/rScale.abs(); 171 scaleVector(*modBurst,rScale);*/ 172 float headRoom = (mNumARFCNs > 1) ? 0.5 : 1.0; 173 scaleVector(*modBurst,txFullScale * headRoom * pow(10,-RSSI/10)/mNumARFCNs); 174 radioVector *newVec = new radioVector(*modBurst,wTime,ARFCN); 175 176 // upsample and filter and freq shift 177 if (mMultipleARFCN) { 178 signalVector *interpVec = polyphaseResampleVector(*((signalVector *)newVec),mOversamplingRate,1,interpolationFilter); 179 //LOG(DEBUG) << "newVec size: " << newVec->size() << ", interpVec: " << interpVec->size(); 180 delete newVec; 181 182 //if (ARFCN!=0) printf("ARFCN: %d\n",ARFCN); 183 multVector(*interpVec,*frequencyShifter[ARFCN]); 184 185 newVec = new radioVector(*interpVec,wTime,ARFCN); 186 delete interpVec; 187 } 188 117 189 mTransmitPriorityQueue.write(newVec); 118 190 … … 151 223 // (It might be an idle pattern.) 152 224 LOG(NOTICE) << "dumping STALE burst in TRX->USRP interface"; 153 const GSM::Time& nextTime = staleBurst->time(); 154 int TN = nextTime.TN(); 155 int modFN = nextTime.FN() % fillerModulus[TN]; 156 delete fillerTable[modFN][TN]; 157 fillerTable[modFN][TN] = staleBurst; 225 if (staleBurst->ARFCN()==0) { 226 const GSM::Time& nextTime = staleBurst->time(); 227 int TN = nextTime.TN(); 228 int modFN = nextTime.FN() % fillerModulus[TN]; 229 // FIXME!!!!!! 230 delete fillerTable[modFN][TN]; 231 fillerTable[modFN][TN] = staleBurst; 232 } 233 else 234 delete staleBurst; 158 235 } 159 236 … … 161 238 int modFN = nowTime.FN() % fillerModulus[nowTime.TN()]; 162 239 240 bool addFiller = true; 241 radioVector *sendVec = NULL; 242 163 243 // if queue contains data at the desired timestamp, stick it into FIFO 164 if (radioVector *next = (radioVector*) mTransmitPriorityQueue.getCurrentBurst(nowTime)) { 165 LOG(DEBUG) << "transmitFIFO: wrote burst " << next << " at time: " << nowTime; 166 delete fillerTable[modFN][TN]; 167 fillerTable[modFN][TN] = new signalVector(*(next)); 168 mRadioInterface->driveTransmitRadio(*(next),(mChanType[TN]==NONE)); //fillerTable[modFN][TN])); 169 delete next; 170 #ifdef TRANSMIT_LOGGING 171 if (nowTime.TN()==TRANSMIT_LOGGING) { 172 unModulateVector(*(fillerTable[modFN][TN])); 173 } 174 #endif 175 return; 176 } 244 while (radioVector *next = (radioVector*) mTransmitPriorityQueue.getCurrentBurst(nowTime)) { 245 //LOG(DEBUG) << "transmitFIFO: wrote burst " << next << " at time: " << nowTime; 246 if (next->ARFCN() == 0) { 247 delete fillerTable[modFN][TN]; 248 fillerTable[modFN][TN] = new signalVector(*(next)); 249 addFiller = false; 250 } 251 if (!sendVec) 252 sendVec = next; 253 else { 254 addVector(*sendVec,*next); 255 delete next; 256 } 257 } 258 259 if (addFiller) { 260 // pull filler data, and push to radio FIFO 261 int dummy = 0; 262 radioVector *tmpVec = new radioVector(*fillerTable[modFN][TN],nowTime,dummy); 263 if (!sendVec) 264 sendVec = tmpVec; 265 else { 266 addVector(*sendVec,*tmpVec); 267 delete tmpVec; 268 } 269 } 270 271 //LOG(DEBUG) << "sendVec size: " << sendVec->size(); 177 272 178 273 // otherwise, pull filler data, and push to radio FIFO 179 mRadioInterface->driveTransmitRadio(*(fillerTable[modFN][TN]),(mChanType[TN]==NONE)); 180 #ifdef TRANSMIT_LOGGING 181 if (nowTime.TN()==TRANSMIT_LOGGING) 182 unModulateVector(*fillerTable[modFN][TN]); 183 #endif 274 mRadioInterface->driveTransmitRadio(*sendVec,(mChanType[0][TN]==NONE)); 275 276 delete sendVec; 184 277 185 278 } … … 187 280 void Transceiver::setModulus(int timeslot) 188 281 { 189 switch (mChanType[timeslot]) { 282 283 switch (mChanType[0][timeslot]) { 190 284 case NONE: 191 285 case I: … … 210 304 211 305 212 Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime)306 CorrType Transceiver::expectedCorrType(GSM::Time currTime, int ARFCN) 213 307 { 214 308 … … 216 310 unsigned burstFN = currTime.FN(); 217 311 218 switch (mChanType[ burstTN]) {312 switch (mChanType[ARFCN][burstTN]) { 219 313 case NONE: 220 314 return OFF; … … 274 368 } 275 369 276 SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, 277 int &RSSI, 278 int &timingOffset) 279 { 280 bool needDFE = (mMaxExpectedDelay > 1); 281 282 radioVector *rxBurst = (radioVector *) mReceiveFIFO->get(); 283 284 if (!rxBurst) return NULL; 285 286 LOG(DEBUG) << "receiveFIFO: read radio vector at time: " << rxBurst->time() << ", new size: " << mReceiveFIFO->size(); 287 370 void Transceiver::pullRadioVector() 371 { 372 radioVector *rxBurst = NULL; 373 rxBurst = (radioVector *) mReceiveFIFO->get(); 374 if (!rxBurst) return; 375 376 //LOG(DEBUG) << "receiveFIFO: read radio vector " << rxBurst << " at time: " << rxBurst->time() << ", new size: " << mReceiveFIFO->size(); 377 378 GSM::Time theTime = rxBurst->time(); 288 379 int timeslot = rxBurst->time().TN(); 289 380 290 CorrType corrType = expectedCorrType(rxBurst->time()); 291 292 if ((corrType==OFF) || (corrType==IDLE)) { 293 delete rxBurst; 294 return NULL; 295 } 296 297 // check to see if received burst has sufficient 298 signalVector *vectorBurst = rxBurst; 299 complex amplitude = 0.0; 300 float TOA = 0.0; 301 float avgPwr = 0.0; 302 if (!energyDetect(*vectorBurst,20*mSamplesPerSymbol,mEnergyThreshold,&avgPwr)) { 303 LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->time(); 304 double framesElapsed = rxBurst->time()-prevFalseDetectionTime; 305 if (framesElapsed > 50) { // if we haven't had any false detections for a while, lower threshold 306 mEnergyThreshold -= 10.0/10.0; 307 prevFalseDetectionTime = rxBurst->time(); 308 } 309 delete rxBurst; 310 return NULL; 311 } 312 LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->time(); 313 314 // run the proper correlator 315 bool success = false; 316 if (corrType==TSC) { 317 LOG(DEBUG) << "looking for TSC at time: " << rxBurst->time(); 318 signalVector *channelResp; 319 double framesElapsed = rxBurst->time()-channelEstimateTime[timeslot]; 320 bool estimateChannel = false; 321 if ((framesElapsed > 50) || (channelResponse[timeslot]==NULL)) { 322 if (channelResponse[timeslot]) delete channelResponse[timeslot]; 323 if (DFEForward[timeslot]) delete DFEForward[timeslot]; 324 if (DFEFeedback[timeslot]) delete DFEFeedback[timeslot]; 325 channelResponse[timeslot] = NULL; 326 DFEForward[timeslot] = NULL; 327 DFEFeedback[timeslot] = NULL; 328 estimateChannel = true; 329 } 330 if (!needDFE) estimateChannel = false; 331 float chanOffset; 332 success = analyzeTrafficBurst(*vectorBurst, 333 mTSC, 334 3.0, 335 mSamplesPerSymbol, 336 &litude, 337 &TOA, 338 mMaxExpectedDelay, 339 estimateChannel, 340 &channelResp, 341 &chanOffset); 342 if (success) { 343 LOG(DEBUG) << "FOUND TSC!!!!!! " << amplitude << " " << TOA; 344 mEnergyThreshold -= 1.0F/10.0F; 345 if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0; 346 SNRestimate[timeslot] = amplitude.norm2()/(mEnergyThreshold*mEnergyThreshold+1.0); // this is not highly accurate 347 if (estimateChannel) { 348 LOG(DEBUG) << "estimating channel..."; 349 channelResponse[timeslot] = channelResp; 350 chanRespOffset[timeslot] = chanOffset; 351 chanRespAmplitude[timeslot] = amplitude; 352 scaleVector(*channelResp, complex(1.0,0.0)/amplitude); 353 designDFE(*channelResp, SNRestimate[timeslot], 7, &DFEForward[timeslot], &DFEFeedback[timeslot]); 354 channelEstimateTime[timeslot] = rxBurst->time(); 355 LOG(DEBUG) << "SNR: " << SNRestimate[timeslot] << ", DFE forward: " << *DFEForward[timeslot] << ", DFE backward: " << *DFEFeedback[timeslot]; 356 } 357 } 358 else { 359 double framesElapsed = rxBurst->time()-prevFalseDetectionTime; 360 LOG(DEBUG) << "wTime: " << rxBurst->time() << ", pTime: " << prevFalseDetectionTime << ", fElapsed: " << framesElapsed; 361 mEnergyThreshold += 10.0F/10.0F*exp(-framesElapsed); 362 prevFalseDetectionTime = rxBurst->time(); 363 channelResponse[timeslot] = NULL; 364 } 365 } 366 else { 367 // RACH burst 368 success = detectRACHBurst(*vectorBurst, 369 5.0, // detection threshold 370 mSamplesPerSymbol, 371 &litude, 372 &TOA); 373 if (success) { 374 LOG(DEBUG) << "FOUND RACH!!!!!! " << amplitude << " " << TOA; 375 mEnergyThreshold -= (1.0F/10.0F); 376 if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0; 377 channelResponse[timeslot] = NULL; 378 } 379 else { 380 double framesElapsed = rxBurst->time()-prevFalseDetectionTime; 381 mEnergyThreshold += (1.0F/10.0F)*exp(-framesElapsed); 382 prevFalseDetectionTime = rxBurst->time(); 383 } 384 } 385 LOG(DEBUG) << "energy Threshold = " << mEnergyThreshold; 386 387 // demodulate burst 388 SoftVector *burst = NULL; 389 if ((rxBurst) && (success)) { 390 if ((corrType==RACH) || (!needDFE)) { 391 burst = demodulateBurst(*vectorBurst, 392 *gsmPulse, 393 mSamplesPerSymbol, 394 amplitude,TOA); 395 } 396 else { // TSC 397 scaleVector(*vectorBurst,complex(1.0,0.0)/amplitude); 398 burst = equalizeBurst(*vectorBurst, 399 TOA-chanRespOffset[timeslot], 400 mSamplesPerSymbol, 401 *DFEForward[timeslot], 402 *DFEFeedback[timeslot]); 403 } 404 wTime = rxBurst->time(); 405 // FIXME: what is full scale for the USRP? we get more that 12 bits of resolution... 406 RSSI = (int) floor(20.0*log10(rxFullScale/amplitude.abs())); 407 LOG(DEBUG) << "RSSI: " << RSSI; 408 timingOffset = (int) round(TOA*256.0/mSamplesPerSymbol); 409 } 410 411 //if (burst) LOG(DEBUG) << "burst: " << *burst << '\n'; 381 for (int i = 0; i < mNumARFCNs; i++) { 382 CorrType corrType = expectedCorrType(rxBurst->time(),i); 383 if ((corrType == OFF) || (corrType == IDLE)) continue; 384 radioVector *ARFCNVec = new radioVector(*(signalVector *)rxBurst,theTime,i); 385 if (mMultipleARFCN) { 386 multVector(*ARFCNVec,*frequencyShifter[mNumARFCNs-1-i]); 387 signalVector *rcvVec = polyphaseResampleVector(*ARFCNVec,1,mOversamplingRate,decimationFilter); 388 delete ARFCNVec; 389 ARFCNVec = new radioVector(*rcvVec,theTime,i); 390 delete rcvVec; 391 } 392 //LOG(INFO) << "putting " << ARFCNVec << " in queue " << i << " at time " << theTime; 393 mDemodFIFO[i]->put(ARFCNVec); 394 } 412 395 413 396 delete rxBurst; 414 415 return burst;416 397 } 417 398 418 399 void Transceiver::start() 419 400 { 420 mControlServiceLoopThread->start((void * (*)(void*))ControlServiceLoopAdapter,(void*) this); 401 for(int i = 0; i < mNumARFCNs; i++) { 402 ThreadStruct *cs = new ThreadStruct; 403 cs->trx = this; 404 cs->ARFCN = i; 405 mControlServiceLoopThread[i]->start((void * (*)(void*))ControlServiceLoopAdapter,(void*) cs); 406 } 421 407 } 422 408 … … 429 415 430 416 431 void Transceiver::driveControl( )417 void Transceiver::driveControl(unsigned ARFCN) 432 418 { 433 419 … … 439 425 buffer[0] = '\0'; 440 426 441 msgLen = mControlSocket.read(buffer); 427 msgLen = mControlSocket[ARFCN]->read(buffer); 428 429 mControlLock.lock(); 442 430 443 431 if (msgLen < 1) { 432 mControlLock.unlock(); 444 433 return; 445 434 } … … 454 443 455 444 if (strcmp(cmdcheck,"CMD")!=0) { 456 LOG(WARNING) << "bogus message on control interface"; 445 LOG(ERR) << "bogus message on control interface"; 446 mControlLock.unlock(); 457 447 return; 458 448 } … … 473 463 mPower = -20; 474 464 mRadioInterface->start(); 465 466 // Start radio interface threads. 467 writeClockInterface(); 475 468 generateRACHSequence(*gsmPulse,mSamplesPerSymbol); 476 469 477 // Start radio interface threads.470 mRFIFOServiceLoopThread->start((void * (*)(void*))RFIFOServiceLoopAdapter,(void*) this); 478 471 mFIFOServiceLoopThread->start((void * (*)(void*))FIFOServiceLoopAdapter,(void*) this); 479 mTransmitPriorityQueueServiceLoopThread->start((void * (*)(void*))TransmitPriorityQueueServiceLoopAdapter,(void*) this); 480 writeClockInterface(); 472 473 for (int i = 0; i < mNumARFCNs; i++) { 474 ThreadStruct *cs = new ThreadStruct; 475 cs->trx = this; 476 cs->ARFCN = i; 477 mTransmitPriorityQueueServiceLoopThread[i]->start((void * (*)(void*))TransmitPriorityQueueServiceLoopAdapter,(void*) cs); 478 Demodulator *demod = new Demodulator(i,this,mStartTime); 479 mDemodulators[i] = demod; 480 if (mNumARFCNs > 1) mDemodServiceLoopThread[i]->start((void * (*)(void*))DemodServiceLoopAdapter,(void*) demod); 481 } 482 483 //mRFIFOServiceLoopThread->start((void * (*)(void*))RFIFOServiceLoopAdapter,(void*) this); 484 //mFIFOServiceLoopThread->start((void * (*)(void*))FIFOServiceLoopAdapter,(void*) this); 485 481 486 482 487 mOn = true; … … 485 490 } 486 491 else if (strcmp(command,"SETMAXDLY")==0) { 492 // FIXME -- Use the configuration table instead. 487 493 //set expected maximum time-of-arrival 488 494 int maxDelay; … … 492 498 } 493 499 else if (strcmp(command,"SETRXGAIN")==0) { 500 // FIXME -- Use the configuration table instead. 494 501 //set expected maximum time-of-arrival 495 502 int newGain; … … 499 506 } 500 507 else if (strcmp(command,"NOISELEV")==0) { 508 // FIXME -- Use the status table instead. 501 509 if (mOn) { 502 510 sprintf(response,"RSP NOISELEV 0 %d", 503 (int) round(20.0*log10(rxFullScale/m EnergyThreshold)));511 (int) round(20.0*log10(rxFullScale/mDemodulators[0]->getEnergyThreshold()))); 504 512 } 505 513 else { … … 514 522 sprintf(response,"RSP SETPOWER 1 %d",dbPwr); 515 523 else { 516 mPower = dbPwr; 517 mRadioInterface->setPowerAttenuation(dbPwr); 524 if (ARFCN==0) { 525 mPower = dbPwr; 526 mRadioInterface->setPowerAttenuation(dbPwr + gConfig.getNum("TRX.TxAttenOffset")); 527 } 518 528 sprintf(response,"RSP SETPOWER 0 %d",dbPwr); 519 529 } 520 530 } 521 531 else if (strcmp(command,"ADJPOWER")==0) { 532 // FIXME -- Use the configuration table instead. 522 533 // adjust power in dB steps 523 534 int dbStep; … … 526 537 sprintf(response,"RSP ADJPOWER 1 %d",mPower); 527 538 else { 528 mPower += dbStep; 539 if (ARFCN==0) 540 mPower += dbStep; 529 541 sprintf(response,"RSP ADJPOWER 0 %d",mPower); 530 542 } 531 543 } 532 #define FREQOFFSET 0//11.2e3533 544 else if (strcmp(command,"RXTUNE")==0) { 534 545 // tune receiver 535 546 int freqKhz; 536 547 sscanf(buffer,"%3s %s %d",cmdcheck,command,&freqKhz); 537 mRxFreq = freqKhz*1.0e3+ FREQOFFSET;538 if ( !mRadioInterface->tuneRx(mRxFreq,gConfig.getNum("TRX.RadioFrequencyOffset"))) {548 mRxFreq = freqKhz*1.0e3+mFreqOffset; 549 if ((ARFCN==0) && !mRadioInterface->tuneRx(mRxFreq,gConfig.getNum("TRX.RadioFrequencyOffset"))) { 539 550 LOG(ALERT) << "RX failed to tune"; 540 551 sprintf(response,"RSP RXTUNE 1 %d",freqKhz); … … 548 559 sscanf(buffer,"%3s %s %d",cmdcheck,command,&freqKhz); 549 560 //freqKhz = 890e3; 550 mTxFreq = freqKhz*1.0e3+ FREQOFFSET;551 if ( !mRadioInterface->tuneTx(mTxFreq,gConfig.getNum("TRX.RadioFrequencyOffset"))) {561 mTxFreq = freqKhz*1.0e3+mFreqOffset; 562 if ((ARFCN==0) && !mRadioInterface->tuneTx(mTxFreq,gConfig.getNum("TRX.RadioFrequencyOffset"))) { 552 563 LOG(ALERT) << "TX failed to tune"; 553 564 sprintf(response,"RSP TXTUNE 1 %d",freqKhz); … … 563 574 sprintf(response,"RSP SETTSC 1 %d",TSC); 564 575 else { 565 mTSC = TSC; 566 generateMidamble(*gsmPulse,mSamplesPerSymbol,TSC); 576 if (ARFCN==0) { 577 mTSC = TSC; 578 generateMidamble(*gsmPulse,mSamplesPerSymbol,TSC); 579 } 567 580 sprintf(response,"RSP SETTSC 0 %d",TSC); 568 581 } … … 573 586 int timeslot; 574 587 sscanf(buffer,"%3s %s %d %d",cmdcheck,command,×lot,&corrCode); 588 //sscanf(buffer,"%3s %s %d %d %d",cmdcheck,command,×lot,&corrCode,&ARFCN); 575 589 if ((timeslot < 0) || (timeslot > 7)) { 576 LOG( WARNING) << "bogus message on control interface";590 LOG(ERR) << "bogus message on control interface"; 577 591 sprintf(response,"RSP SETSLOT 1 %d %d",timeslot,corrCode); 578 return; 579 } 580 mChanType[timeslot] = (ChannelCombination) corrCode; 581 setModulus(timeslot); 582 sprintf(response,"RSP SETSLOT 0 %d %d",timeslot,corrCode); 583 592 } 593 else if ((ARFCN < 0) || (ARFCN >= MAXARFCN)) { 594 LOG(ERR) << "bogus message on control interface"; 595 sprintf(response,"RSP SETSLOT 1 %d %d",timeslot,corrCode); 596 } 597 else { 598 mChanType[ARFCN][timeslot] = (ChannelCombination) corrCode; 599 setModulus(timeslot); 600 sprintf(response,"RSP SETSLOT 0 %d %d",timeslot,corrCode); 601 } 584 602 } 585 603 else { 586 LOG(WARNING) << "bogus command " << command << " on control interface."; 587 } 588 589 mControlSocket.write(response,strlen(response)+1); 590 591 } 592 593 bool Transceiver::driveTransmitPriorityQueue() 594 { 595 604 LOG(ERR) << "bogus command " << command << " on control interface."; 605 } 606 607 mControlSocket[ARFCN]->write(response,strlen(response)+1); 608 609 mControlLock.unlock(); 610 611 612 } 613 614 bool Transceiver::driveTransmitPriorityQueue(unsigned ARFCN) 615 { 616 617 618 #if 1 596 619 char buffer[gSlotLen+50]; 597 620 598 621 // check data socket 599 size_t msgLen = mDataSocket.read(buffer); 622 size_t msgLen = mDataSocket[ARFCN]->read(buffer); 623 624 mTransmitPriorityQueueLock.lock(); 600 625 601 626 if (msgLen!=gSlotLen+1+4+1) { 602 627 LOG(ERR) << "badly formatted packet on GSM->TRX interface"; 628 mTransmitPriorityQueueLock.unlock(); 603 629 return false; 604 630 } … … 626 652 627 653 // periodically update GSM core clock 628 LOG(DEBUG) << "mTransmitDeadlineClock " << mTransmitDeadlineClock629 << " mLastClockUpdateTime " << mLastClockUpdateTime;654 //LOG(DEBUG) << "mTransmitDeadlineClock " << mTransmitDeadlineClock 655 // << " mLastClockUpdateTime " << mLastClockUpdateTime; 630 656 if (mTransmitDeadlineClock > mLastClockUpdateTime + GSM::Time(216,0)) 631 657 writeClockInterface(); 632 658 633 659 634 LOG(DEBUG) << "rcvd. burst at: " << GSM::Time(frameNum,timeSlot);660 //LOG(DEBUG) << "rcvd. burst at: " << GSM::Time(frameNum,timeSlot); 635 661 636 662 int RSSI = (int) buffer[5]; … … 643 669 GSM::Time currTime = GSM::Time(frameNum,timeSlot); 644 670 645 addRadioVector(newBurst,RSSI,currTime); 646 647 LOG(DEBUG) "added burst - time: " << currTime << ", RSSI: " << RSSI; // << ", data: " << newBurst; 671 addRadioVector(newBurst,RSSI,currTime,ARFCN); 672 673 //LOG(DEBUG) "added burst - time: " << currTime << ", RSSI: " << RSSI; // << ", data: " << newBurst; 674 675 mTransmitPriorityQueueLock.unlock(); 676 #else 677 RadioClock *radioClock = (mRadioInterface->getClock()); 678 679 if (mOn) { 680 radioClock->wait(); // wait until clock updates 681 // time to push burst to transmit FIFO 682 mTransmitPriorityQueueLock.lock(); 683 for (int i = 0; i < 4; i++) 684 { 685 int iSlot = radioClock->get().TN(); //mTransmitDeadlineClock.TN(); 686 static BitVector newBurst(gSlotLen); 687 GSM::Time currTime = GSM::Time(mTransmitDeadlineClock.FN()+50,(iSlot+i)%8); 688 addRadioVector(newBurst,0,currTime,ARFCN); 689 //printf("adding %d %d\n",mTransmitDeadlineClock.FN(),iSlot); 690 } 691 mTransmitPriorityQueueLock.unlock(); 692 } 693 #endif 694 648 695 649 696 return true; … … 652 699 } 653 700 654 void Transceiver::driveReceiveFIFO() 655 { 656 701 void Transceiver::driveReceiveFIFO() 702 { 703 mRadioInterface->driveReceiveRadio(); 704 705 pullRadioVector(); 706 } 707 708 709 void Transceiver::driveTransmitFIFO() 710 { 711 712 /** 713 Features a carefully controlled latency mechanism, to 714 assure that transmit packets arrive at the radio/USRP 715 before they need to be transmitted. 716 717 Deadline clock indicates the burst that needs to be 718 pushed into the FIFO right NOW. If transmit queue does 719 not have a burst, stick in filler data. 720 */ 721 722 723 RadioClock *radioClock = (mRadioInterface->getClock()); 724 725 if (mOn) { 726 radioClock->wait(); // wait until clock updates 727 //LOG(DEBUG) << "radio clock " << radioClock->get(); 728 while (radioClock->get() + mTransmitLatency > mTransmitDeadlineClock) { 729 // if underrun, then we're not providing bursts to radio/USRP fast 730 // enough. Need to increase latency by one GSM frame. 731 if (mRadioInterface->isUnderrun()) { 732 // only do latency update every 10 frames, so we don't over update 733 if (radioClock->get() > mLatencyUpdateTime + GSM::Time(100,0)) { 734 mTransmitLatency = mTransmitLatency + GSM::Time(1,0); 735 LOG(NOTICE) << "new latency: " << mTransmitLatency; 736 mLatencyUpdateTime = radioClock->get(); 737 } 738 } 739 else { 740 // if underrun hasn't occurred in the last sec (216 frames) drop 741 // transmit latency by a timeslot 742 if (mTransmitLatency > GSM::Time(1,1)) { 743 if (radioClock->get() > mLatencyUpdateTime + GSM::Time(216,0)) { 744 mTransmitLatency.decTN(); 745 LOG(NOTICE) << "reduced latency: " << mTransmitLatency; 746 mLatencyUpdateTime = radioClock->get(); 747 } 748 } 749 } 750 // time to push burst to transmit FIFO 751 pushRadioVector(mTransmitDeadlineClock); 752 mTransmitDeadlineClock.incTN(); 753 } 754 755 } 756 // FIXME -- This should not be a hard spin. 757 // But any delay here causes us to throw omni_thread_fatal. 758 //else radioClock->wait(); 759 } 760 761 762 763 void Transceiver::writeClockInterface() 764 { 765 char command[50]; 766 // FIME -- See tracker #315. 767 //sprintf(command,"IND CLOCK %llu",(unsigned long long) (mTransmitDeadlineClock.FN()+10)); 768 sprintf(command,"IND CLOCK %llu",(unsigned long long) (mTransmitDeadlineClock.FN()+2)); 769 770 LOG(INFO) << "ClockInterface: sending " << command; 771 772 mClockSocket.write(command,strlen(command)+1); 773 774 mLastClockUpdateTime = mTransmitDeadlineClock; 775 776 } 777 778 void *FIFOServiceLoopAdapter(Transceiver *transceiver) 779 { 780 while (1) { 781 //transceiver->driveReceiveFIFO(); 782 transceiver->driveTransmitFIFO(); 783 pthread_testcancel(); 784 } 785 return NULL; 786 } 787 788 void *RFIFOServiceLoopAdapter(Transceiver *transceiver) 789 { 790 bool isMulti = transceiver->multiARFCN(); 791 while (1) { 792 transceiver->driveReceiveFIFO(); 793 if (!isMulti) transceiver->mDemodulators[0]->driveDemod(true); 794 //transceiver->driveTransmitFIFO(); 795 pthread_testcancel(); 796 } 797 return NULL; 798 } 799 800 801 void *ControlServiceLoopAdapter(ThreadStruct *ts) 802 { 803 Transceiver *transceiver = ts->trx; 804 unsigned ARFCN = ts->ARFCN; 805 while (1) { 806 transceiver->driveControl(ARFCN); 807 pthread_testcancel(); 808 } 809 return NULL; 810 } 811 812 void *DemodServiceLoopAdapter(Demodulator *demodulator) 813 { 814 while(1) { 815 demodulator->driveDemod(); 816 pthread_testcancel(); 817 } 818 return NULL; 819 } 820 821 void *TransmitPriorityQueueServiceLoopAdapter(ThreadStruct *ts) 822 { 823 Transceiver *transceiver = ts->trx; 824 unsigned ARFCN = ts->ARFCN; 825 while (1) { 826 bool stale = false; 827 // Flush the UDP packets until a successful transfer. 828 while (!transceiver->driveTransmitPriorityQueue(ARFCN)) { 829 stale = true; 830 } 831 if (stale) { 832 // If a packet was stale, remind the GSM stack of the clock. 833 transceiver->writeClockInterface(); 834 } 835 pthread_testcancel(); 836 } 837 return NULL; 838 } 839 840 841 Demodulator::Demodulator(int wARFCN, 842 Transceiver *wTRX, 843 GSM::Time wStartTime) 844 { 845 846 assert(wTRX); 847 848 mARFCN = wARFCN; 849 mTRX = wTRX; 850 mRadioInterface = mTRX->radioInterface(); 851 mTRXDataSocket = mTRX->dataSocket(mARFCN); 852 mSamplesPerSymbol = mTRX->samplesPerSymbol(); 853 mDemodFIFO = mTRX->demodFIFO(mARFCN); 854 signalVector *gsmPulse = mTRX->GSMPulse(); 855 mTSC = mTRX->getTSC(); 856 857 rxFullScale = mRadioInterface->fullScaleOutputValue(); 858 859 LOG(DEBUG) << "Creating demodulator for ARFCN " << mARFCN << " with TSC " << mTSC; 860 861 for (unsigned i = 0; i < 8; i++) { 862 channelResponse[i] = NULL; 863 DFEForward[i] = NULL; 864 DFEFeedback[i] = NULL; 865 channelEstimateTime[i] = wStartTime; 866 mEnergyThreshold = 7.07; 867 } 868 869 prevFalseDetectionTime = wStartTime; 870 871 } 872 873 void Demodulator::driveDemod(bool wSingleARFCN) 874 { 875 876 //LOG(DEBUG) << "calling driveDemod "; 877 878 radioVector *demodBurst = NULL; 657 879 SoftVector *rxBurst = NULL; 658 880 int RSSI; … … 660 882 GSM::Time burstTime; 661 883 662 mRadioInterface->driveReceiveRadio(); 663 664 rxBurst = pullRadioVector(burstTime,RSSI,TOA); 884 //RadioClock *radioClock = (mRadioInterface->getClock()); 885 //radioClock->wait(); 886 887 demodBurst = mDemodFIFO->get(); 888 if (!wSingleARFCN) { 889 while (!demodBurst) { 890 RadioClock *radioClock = (mRadioInterface->getClock()); 891 radioClock->wait(); 892 demodBurst = mDemodFIFO->get(); 893 } 894 } 895 else { 896 if (!demodBurst) return; 897 } 898 899 mMaxExpectedDelay = mTRX->maxDelay(); 900 901 rxBurst = demodRadioVector(demodBurst,burstTime,RSSI,TOA); 665 902 666 903 if (rxBurst) { 667 904 668 905 LOG(DEBUG) << "burst parameters: " 906 << " ARFCN: " << mARFCN 669 907 << " time: " << burstTime 670 908 << " RSSI: " << RSSI … … 687 925 delete rxBurst; 688 926 689 mDataSocket.write(burstString,gSlotLen+10); 690 } 691 692 } 693 694 void Transceiver::driveTransmitFIFO() 695 { 696 697 /** 698 Features a carefully controlled latency mechanism, to 699 assure that transmit packets arrive at the radio/USRP 700 before they need to be transmitted. 701 702 Deadline clock indicates the burst that needs to be 703 pushed into the FIFO right NOW. If transmit queue does 704 not have a burst, stick in filler data. 705 */ 706 707 708 RadioClock *radioClock = (mRadioInterface->getClock()); 709 710 if (mOn) { 711 //radioClock->wait(); // wait until clock updates 712 LOG(DEBUG) << "radio clock " << radioClock->get(); 713 while (radioClock->get() + mTransmitLatency > mTransmitDeadlineClock) { 714 // if underrun, then we're not providing bursts to radio/USRP fast 715 // enough. Need to increase latency by one GSM frame. 716 if (mRadioInterface->isUnderrun()) { 717 // only do latency update every 10 frames, so we don't over update 718 if (radioClock->get() > mLatencyUpdateTime + GSM::Time(10,0)) { 719 mTransmitLatency = mTransmitLatency + GSM::Time(1,0); 720 LOG(INFO) << "new latency: " << mTransmitLatency; 721 mLatencyUpdateTime = radioClock->get(); 722 } 927 mTRXDataSocket->write(burstString,gSlotLen+10); 928 } 929 930 } 931 932 SoftVector *Demodulator::demodRadioVector(radioVector *rxBurst, 933 GSM::Time &wTime, 934 int &RSSI, 935 int &timingOffset) 936 { 937 938 bool needDFE = (mMaxExpectedDelay > 1); 939 940 int timeslot = rxBurst->time().TN(); 941 942 CorrType corrType = mTRX->expectedCorrType(rxBurst->time(),mARFCN); 943 944 //LOG(INFO) << "Demoding ptr " << rxBurst << " at " << rxBurst->time() << " for ARFCN " << mARFCN; 945 946 if ((corrType==OFF) || (corrType==IDLE)) { 947 //LOG(DEBUG) << "Illegal burst"; 948 delete rxBurst; 949 return NULL; 950 } 951 952 // check to see if received burst has sufficient 953 signalVector *vectorBurst = rxBurst; 954 //LOG(DEBUG) << "vectorBurst: " << vectorBurst << " rxBurst: " << rxBurst; 955 complex amplitude = 0.0; 956 float TOA = 0.0; 957 float avgPwr = 0.0; 958 /*if (!energyDetect(*vectorBurst,20*mSamplesPerSymbol,mEnergyThreshold,&avgPwr)) { 959 LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->time(); 960 double framesElapsed = rxBurst->time()-prevFalseDetectionTime; 961 if (framesElapsed > 50) { // if we haven't had any false detections for a while, lower threshold 962 //mEnergyThreshold -= 1.0; 963 prevFalseDetectionTime = rxBurst->time(); 964 } 965 //LOG(INFO) << "Low burst energy."; 966 delete rxBurst; 967 LOG(INFO) << "Deleting " << rxBurst; 968 return NULL; 969 }*/ 970 LOG(DEBUG) << "Estimated Energy: " << sqrt(avgPwr) << ", at time " << rxBurst->time(); 971 972 // run the proper correlator 973 bool success = false; 974 if (corrType==TSC) { 975 LOG(DEBUG) << "looking for TSC at time: " << rxBurst->time(); 976 signalVector *channelResp; 977 double framesElapsed = rxBurst->time()-channelEstimateTime[timeslot]; 978 bool estimateChannel = false; 979 //if ((framesElapsed > 50) || (channelResponse[timeslot]==NULL)) { 980 { 981 if (channelResponse[timeslot]) delete channelResponse[timeslot]; 982 if (DFEForward[timeslot]) delete DFEForward[timeslot]; 983 if (DFEFeedback[timeslot]) delete DFEFeedback[timeslot]; 984 channelResponse[timeslot] = NULL; 985 DFEForward[timeslot] = NULL; 986 DFEFeedback[timeslot] = NULL; 987 estimateChannel = true; 988 } 989 estimateChannel = true; 990 if (!needDFE) estimateChannel = false; 991 float chanOffset; 992 993 success = analyzeTrafficBurst(*vectorBurst, 994 mTSC, 995 3.0, 996 mSamplesPerSymbol, 997 &litude, 998 &TOA, 999 mMaxExpectedDelay, 1000 estimateChannel, 1001 &channelResp, 1002 &chanOffset); 1003 1004 if (success) { 1005 LOG(DEBUG) << "FOUND TSC!!!!!! " << amplitude << " " << TOA; 1006 //mEnergyThreshold -= 0.1F; 1007 if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0; 1008 SNRestimate[timeslot] = amplitude.norm2()/(mEnergyThreshold*mEnergyThreshold+1.0); // this is not highly accurate 1009 if (estimateChannel) { 1010 LOG(DEBUG) << "estimating channel..."; 1011 channelResponse[timeslot] = channelResp; 1012 chanRespOffset[timeslot] = chanOffset; 1013 chanRespAmplitude[timeslot] = amplitude; 1014 scaleVector(*channelResp, complex(1.0,0.0)/amplitude); 1015 designDFE(*channelResp, SNRestimate[timeslot], 7, &DFEForward[timeslot], &DFEFeedback[timeslot]); 1016 channelEstimateTime[timeslot] = rxBurst->time(); 1017 LOG(DEBUG) << "SNR: " << SNRestimate[timeslot] << ", DFE forward: " << *DFEForward[timeslot] << ", DFE backward: " << *DFEFeedback[timeslot]; 723 1018 } 724 else { 725 // if underrun hasn't occurred in the last sec (216 frames) drop 726 // transmit latency by a timeslot 727 if (mTransmitLatency > GSM::Time(1,1)) { 728 if (radioClock->get() > mLatencyUpdateTime + GSM::Time(216,0)) { 729 mTransmitLatency.decTN(); 730 LOG(INFO) << "reduced latency: " << mTransmitLatency; 731 mLatencyUpdateTime = radioClock->get(); 732 } 733 } 734 } 735 // time to push burst to transmit FIFO 736 pushRadioVector(mTransmitDeadlineClock); 737 mTransmitDeadlineClock.incTN(); 738 } 739 740 } 741 // FIXME -- This should not be a hard spin. 742 // But any delay here causes us to throw omni_thread_fatal. 743 //else radioClock->wait(); 744 } 745 746 747 748 void Transceiver::writeClockInterface() 749 { 750 char command[50]; 751 // FIXME -- This should be adaptive. 752 sprintf(command,"IND CLOCK %llu",(unsigned long long) (mTransmitDeadlineClock.FN()+2)); 753 754 LOG(INFO) << "ClockInterface: sending " << command; 755 756 mClockSocket.write(command,strlen(command)+1); 757 758 mLastClockUpdateTime = mTransmitDeadlineClock; 759 760 } 761 762 763 764 765 void *FIFOServiceLoopAdapter(Transceiver *transceiver) 766 { 767 while (1) { 768 transceiver->driveReceiveFIFO(); 769 transceiver->driveTransmitFIFO(); 770 pthread_testcancel(); 771 } 772 return NULL; 773 } 774 775 void *ControlServiceLoopAdapter(Transceiver *transceiver) 776 { 777 while (1) { 778 transceiver->driveControl(); 779 pthread_testcancel(); 780 } 781 return NULL; 782 } 783 784 void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *transceiver) 785 { 786 while (1) { 787 bool stale = false; 788 // Flush the UDP packets until a successful transfer. 789 while (!transceiver->driveTransmitPriorityQueue()) { 790 stale = true; 791 } 792 if (stale) { 793 // If a packet was stale, remind the GSM stack of the clock. 794 transceiver->writeClockInterface(); 795 } 796 pthread_testcancel(); 797 } 798 return NULL; 799 } 1019 } 1020 else { 1021 double framesElapsed = rxBurst->time()-prevFalseDetectionTime; 1022 LOG(DEBUG) << "wTime: " << rxBurst->time() << ", pTime: " << prevFalseDetectionTime << ", fElapsed: " << framesElapsed; 1023 //mEnergyThreshold += 0.1F*exp(-framesElapsed); 1024 prevFalseDetectionTime = rxBurst->time(); 1025 channelResponse[timeslot] = NULL; 1026 } 1027 } 1028 else { 1029 // RACH burst 1030 success = detectRACHBurst(*vectorBurst, 1031 3.0, // detection threshold 1032 mSamplesPerSymbol, 1033 &litude, 1034 &TOA); 1035 if (success) { 1036 LOG(DEBUG) << "FOUND RACH!!!!!! " << amplitude << " " << TOA; 1037 //mEnergyThreshold -= 0.1F; 1038 if (mEnergyThreshold < 0.0) mEnergyThreshold = 0.0; 1039 channelResponse[timeslot] = NULL; 1040 } 1041 else { 1042 double framesElapsed = rxBurst->time()-prevFalseDetectionTime; 1043 //mEnergyThreshold += 0.1F*exp(-framesElapsed); 1044 prevFalseDetectionTime = rxBurst->time(); 1045 } 1046 } 1047 LOG(DEBUG) << "energy Threshold = " << mEnergyThreshold; 1048 1049 // demodulate burst 1050 SoftVector *burst = NULL; 1051 if ((rxBurst) && (success)) { 1052 if ((corrType==RACH) || (!needDFE)) { 1053 burst = demodulateBurst(*vectorBurst, 1054 *gsmPulse, 1055 mSamplesPerSymbol, 1056 amplitude,TOA); 1057 } 1058 else { // TSC 1059 scaleVector(*vectorBurst,complex(1.0,0.0)/amplitude); 1060 burst = equalizeBurst(*vectorBurst, 1061 TOA-chanRespOffset[timeslot], 1062 mSamplesPerSymbol, 1063 *DFEForward[timeslot], 1064 *DFEFeedback[timeslot]); 1065 } 1066 wTime = rxBurst->time(); 1067 // FIXME: what is full scale for the USRP? we get more that 12 bits of resolution... 1068 RSSI = (int) floor(20.0*log10(rxFullScale/amplitude.abs())); 1069 LOG(DEBUG) << "RSSI: " << RSSI; 1070 timingOffset = (int) round(TOA*256.0/mSamplesPerSymbol); 1071 } 1072 1073 //if (burst) LOG(DEEPDEBUG) << "burst: " << *burst << '\n'; 1074 LOG(DEBUG) << "Deleting rxBurst"; 1075 delete rxBurst; 1076 1077 return burst; 1078 } -
openbts/trunk/TransceiverRAD1/Transceiver.h
r2242 r3689 41 41 //#define TRANSMIT_LOGGING 1 42 42 43 #define MAXARFCN 5 44 45 46 /** Codes for burst types of received bursts*/ 47 typedef enum { 48 OFF, ///< timeslot is off 49 TSC, ///< timeslot should contain a normal burst 50 RACH, ///< timeslot should contain an access burst 51 IDLE ///< timeslot is an idle (or dummy) burst 52 } CorrType; 53 54 class Demodulator; 55 class Transceiver; 56 57 typedef struct ThreadStruct { 58 Transceiver *trx; 59 unsigned ARFCN; 60 } ThreadStruct; 61 43 62 /** The Transceiver class, responsible for physical layer of basestation */ 44 63 class Transceiver { … … 49 68 GSM::Time mLatencyUpdateTime; ///< last time latency was updated 50 69 51 UDPSocket mDataSocket; ///< socket for writing to/reading from GSM core52 UDPSocket mControlSocket; ///< socket for writing/reading control commands from GSM core70 UDPSocket *mDataSocket[MAXARFCN]; ///< socket for writing to/reading from GSM core 71 UDPSocket *mControlSocket[MAXARFCN]; ///< socket for writing/reading control commands from GSM core 53 72 UDPSocket mClockSocket; ///< socket for writing clock updates to GSM core 54 73 … … 56 75 VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts 57 76 VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts 77 VectorFIFO* mDemodFIFO[MAXARFCN]; 58 78 59 79 Thread *mFIFOServiceLoopThread; ///< thread to push/pull bursts into transmit/receive FIFO 60 Thread *mControlServiceLoopThread; ///< thread to process control messages from GSM core 61 Thread *mTransmitPriorityQueueServiceLoopThread;///< thread to process transmit bursts from GSM core 80 Thread *mRFIFOServiceLoopThread; 81 Thread *mDemodServiceLoopThread[MAXARFCN]; ///< threads for demodulating individual ARFCNs 82 Thread *mControlServiceLoopThread[MAXARFCN]; ///< thread to process control messages from GSM core 83 Thread *mTransmitPriorityQueueServiceLoopThread[MAXARFCN];///< thread to process transmit bursts from GSM core 62 84 63 85 GSM::Time mTransmitDeadlineClock; ///< deadline for pushing bursts into transmit FIFO 64 86 GSM::Time mLastClockUpdateTime; ///< last time clock update was sent up to core 87 GSM::Time mStartTime; 65 88 66 89 RadioInterface *mRadioInterface; ///< associated radioInterface object 67 90 double txFullScale; ///< full scale input to radio 68 double rxFullScale; ///< full scale output to radio 69 70 /** Codes for burst types of received bursts*/ 71 typedef enum { 72 OFF, ///< timeslot is off 73 TSC, ///< timeslot should contain a normal burst 74 RACH, ///< timeslot should contain an access burst 75 IDLE ///< timeslot is an idle (or dummy) burst 76 } CorrType; 77 91 double rxFullScale; 92 93 Mutex mControlLock; 94 Mutex mTransmitPriorityQueueLock; 95 96 bool mLoadTest; 78 97 79 98 /** Codes for channel combinations */ … … 100 119 void addRadioVector(BitVector &burst, 101 120 int RSSI, 102 GSM::Time &wTime); 121 GSM::Time &wTime, 122 int ARFCN); 103 123 104 124 /** Push modulated burst into transmit FIFO corresponding to a particular timestamp */ … … 106 126 107 127 /** Pull and demodulate a burst from the receive FIFO */ 108 SoftVector *pullRadioVector(GSM::Time &wTime, 109 int &RSSI, 110 int &timingOffset); 128 void pullRadioVector(void); 111 129 112 130 /** Set modulus for specific timeslot */ 113 131 void setModulus(int timeslot); 114 132 115 /** return the expected burst type for the specified timestamp */116 CorrType expectedCorrType(GSM::Time currTime);117 118 133 /** send messages over the clock socket */ 119 134 void writeClockInterface(void); … … 124 139 125 140 bool mOn; ///< flag to indicate that transceiver is powered on 126 ChannelCombination mChanType[ 8]; ///< channel types for all timeslots141 ChannelCombination mChanType[MAXARFCN][8]; ///< channel types for all timeslots 127 142 double mTxFreq; ///< the transmit frequency 128 143 double mRxFreq; ///< the receive frequency 129 144 int mPower; ///< the transmit power in dB 130 145 unsigned mTSC; ///< the midamble sequence code 131 double mEnergyThreshold; ///< threshold to determine if received data is potentially a GSM burst132 GSM::Time prevFalseDetectionTime; ///< last timestamp of a false energy detection133 146 int fillerModulus[8]; ///< modulus values of all timeslots, in frames 134 147 signalVector *fillerTable[102][8]; ///< table of modulated filler waveforms for all timeslots 135 148 unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols 136 149 137 GSM::Time channelEstimateTime[8]; ///< last timestamp of each timeslot's channel estimate 138 signalVector *channelResponse[8]; ///< most recent channel estimate of all timeslots 139 float SNRestimate[8]; ///< most recent SNR estimate of all timeslots 140 signalVector *DFEForward[8]; ///< most recent DFE feedforward filter of all timeslots 141 signalVector *DFEFeedback[8]; ///< most recent DFE feedback filter of all timeslots 142 float chanRespOffset[8]; ///< most recent timing offset, e.g. TOA, of all timeslots 143 complex chanRespAmplitude[8]; ///< most recent channel amplitude of all timeslots 150 unsigned int mNumARFCNs; 151 bool mMultipleARFCN; 152 unsigned char mOversamplingRate; 153 double mFreqOffset; 154 signalVector *frequencyShifter[MAXARFCN]; 155 signalVector *decimationFilter; 156 signalVector *interpolationFilter; 157 158 Demodulator *mDemodulators[MAXARFCN]; 159 160 161 144 162 145 163 public: … … 156 174 int wSamplesPerSymbol, 157 175 GSM::Time wTransmitLatency, 158 RadioInterface *wRadioInterface); 176 RadioInterface *wRadioInterface, 177 unsigned int wNumARFCNs, 178 unsigned int wOversamplingRate, 179 bool wLoadTest); 159 180 160 181 /** Destructor */ … … 164 185 void start(); 165 186 187 bool multiARFCN() {return mMultipleARFCN;} 188 189 /** return the expected burst type for the specified timestamp */ 190 CorrType expectedCorrType(GSM::Time currTime, int ARFCN); 191 166 192 /** attach the radioInterface receive FIFO */ 167 193 void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;} … … 170 196 void transmitFIFO(VectorFIFO *wFIFO) { mTransmitFIFO = wFIFO;} 171 197 198 VectorFIFO *demodFIFO(unsigned ARFCN) { return mDemodFIFO[ARFCN]; } 199 200 RadioInterface *radioInterface(void) { return mRadioInterface; } 201 202 unsigned samplesPerSymbol(void) { return mSamplesPerSymbol; } 203 204 UDPSocket *dataSocket(int ARFCN) { return mDataSocket[ARFCN]; } 205 206 signalVector *GSMPulse(void) { return gsmPulse; } 207 208 unsigned maxDelay(void) { return mMaxExpectedDelay; } 209 210 unsigned getTSC(void) { return mTSC; } 172 211 173 212 protected: … … 180 219 181 220 /** drive handling of control messages from GSM core */ 182 void driveControl( );221 void driveControl(unsigned ARFCN); 183 222 184 223 /** … … 186 225 @return true if a burst was transferred successfully 187 226 */ 188 bool driveTransmitPriorityQueue( );227 bool driveTransmitPriorityQueue(unsigned ARFCN); 189 228 190 229 friend void *FIFOServiceLoopAdapter(Transceiver *); 191 230 192 friend void *ControlServiceLoopAdapter(Transceiver *); 193 194 friend void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *); 231 friend void *RFIFOServiceLoopAdapter(Transceiver *); 232 233 friend void *ControlServiceLoopAdapter(ThreadStruct *); 234 235 friend void *TransmitPriorityQueueServiceLoopAdapter(ThreadStruct *); 195 236 196 237 void reset(); … … 200 241 void *FIFOServiceLoopAdapter(Transceiver *); 201 242 243 void *RFIFOServiceLoopAdapter(Transceiver *); 244 202 245 /** control message handler thread loop */ 203 void *ControlServiceLoopAdapter(T ransceiver*);246 void *ControlServiceLoopAdapter(ThreadStruct *); 204 247 205 248 /** transmit queueing thread loop */ 206 void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *); 207 249 void *TransmitPriorityQueueServiceLoopAdapter(ThreadStruct *); 250 251 class Demodulator { 252 253 private: 254 255 int mARFCN; 256 Transceiver *mTRX; 257 RadioInterface *mRadioInterface; 258 VectorFIFO *mDemodFIFO; 259 double mEnergyThreshold; ///< threshold to determine if received data is potentially a GSM burst 260 GSM::Time prevFalseDetectionTime; ///< last timestamp of a false energy detection 261 GSM::Time channelEstimateTime[8]; ///< last timestamp of each timeslot's channel estimate 262 signalVector *channelResponse[8]; ///< most recent channel estimate of all timeslots 263 float SNRestimate[8]; ///< most recent SNR estimate of all timeslots 264 signalVector *DFEForward[8]; ///< most recent DFE feedforward filter of all timeslots 265 signalVector *DFEFeedback[8]; ///< most recent DFE feedback filter of all timeslots 266 float chanRespOffset[8]; ///< most recent timing offset, e.g. TOA, of all timeslots 267 complex chanRespAmplitude[8]; ///< most recent channel amplitude of all timeslots 268 signalVector *gsmPulse; 269 unsigned mTSC; 270 unsigned mSamplesPerSymbol; 271 272 UDPSocket *mTRXDataSocket; 273 274 unsigned mMaxExpectedDelay; 275 276 double rxFullScale; ///< full scale output to radio 277 278 SoftVector* demodRadioVector(radioVector *rxBurst, 279 GSM::Time &wTime, 280 int &RSSI, 281 int &timingOffset); 282 283 public: 284 285 Demodulator(int wARFCN, 286 Transceiver *wTRX, 287 GSM::Time wStartTime); 288 289 double getEnergyThreshold() {return mEnergyThreshold;} 290 291 292 //protected: 293 294 void driveDemod(bool wSingleARFCN = true); 295 protected: 296 friend void *DemodServiceLoopAdapter(Demodulator *); 297 298 }; 299 300 void *DemodServiceLoopAdapter(Demodulator *); -
openbts/trunk/TransceiverRAD1/radioInterface.cpp
r2242 r3689 72 72 int wRadioOversampling, 73 73 int wTransceiverOversampling, 74 bool wLoadTest, 75 unsigned int wNumARFCNs, 74 76 GSM::Time wStartTime) 75 77 … … 86 88 mClock.set(wStartTime); 87 89 powerScaling = 1.0; 90 mNumARFCNs = wNumARFCNs; 91 92 loadTest = wLoadTest; 88 93 } 89 94 … … 237 242 mOn = true; 238 243 244 if (loadTest) { 245 int mOversamplingRate = samplesPerSymbol; 246 int numARFCN = mNumARFCNs; 247 signalVector *gsmPulse = generateGSMPulse(2,1); 248 BitVector normalBurstSeg = "0000101010100111110010101010010110101110011000111001101010000"; 249 BitVector normalBurst(BitVector(normalBurstSeg,gTrainingSequence[2]),normalBurstSeg); 250 signalVector *modBurst = modulateBurst(normalBurst,*gsmPulse,8,1); 251 signalVector *modBurst9 = modulateBurst(normalBurst,*gsmPulse,9,1); 252 signalVector *interpolationFilter = createLPF(0.6/mOversamplingRate,6*mOversamplingRate,1); 253 scaleVector(*modBurst,mRadio->fullScaleInputValue()); 254 scaleVector(*modBurst9,mRadio->fullScaleInputValue()); 255 double beaconFreq = -1.0*(numARFCN-1)*200e3; 256 finalVec = new signalVector(156*mOversamplingRate); 257 finalVec9 = new signalVector(157*mOversamplingRate); 258 for (int j = 0; j < numARFCN; j++) { 259 signalVector *frequencyShifter = new signalVector(157*mOversamplingRate); 260 frequencyShifter->fill(1.0); 261 frequencyShift(frequencyShifter,frequencyShifter,2.0*M_PI*(beaconFreq+j*400e3)/(1625.0e3/6.0*mOversamplingRate)); 262 signalVector *interpVec = polyphaseResampleVector(*modBurst,mOversamplingRate,1,interpolationFilter); 263 multVector(*interpVec,*frequencyShifter); 264 addVector(*finalVec,*interpVec); 265 interpVec = polyphaseResampleVector(*modBurst9,mOversamplingRate,1,interpolationFilter); 266 multVector(*interpVec,*frequencyShifter); 267 addVector(*finalVec9,*interpVec); 268 } 269 } 270 271 239 272 } 240 273 … … 288 321 if (rcvClock.FN() >= 0) { 289 322 //LOG(DEBUG) << "FN: " << rcvClock.FN(); 323 int dummyARFCN = 0; 290 324 radioVector *rxBurst = NULL; 291 325 if (!loadTest) 292 rxBurst = new radioVector(rxVector,tmpTime );326 rxBurst = new radioVector(rxVector,tmpTime,dummyARFCN); 293 327 else { 294 328 if (tN % 4 == 0) 295 rxBurst = new radioVector(*finalVec9,tmpTime );329 rxBurst = new radioVector(*finalVec9,tmpTime,dummyARFCN); 296 330 else 297 rxBurst = new radioVector(*finalVec,tmpTime );331 rxBurst = new radioVector(*finalVec,tmpTime,dummyARFCN); 298 332 } 299 333 mReceiveFIFO.put(rxBurst); -
openbts/trunk/TransceiverRAD1/radioInterface.h
r2305 r3689 41 41 42 42 GSM::Time mTime; ///< the burst's GSM timestamp 43 int mARFCN; 43 44 44 45 public: 45 46 /** constructor */ 46 47 radioVector(const signalVector& wVector, 47 GSM::Time& wTime): signalVector(wVector),mTime(wTime) {}; 48 GSM::Time& wTime, 49 int& wARFCN): signalVector(wVector),mTime(wTime),mARFCN(wARFCN){}; 48 50 49 51 /** timestamp read and write operators */ 50 52 GSM::Time time() const { return mTime;} 51 53 void time(const GSM::Time& wTime) { mTime = wTime;} 54 55 /** ARFCN read and write operators */ 56 int ARFCN() const { return mARFCN;} 57 void ARFCN(const int& wARFCN) { mARFCN = wARFCN;} 52 58 53 59 /** comparison operator, used for sorting */ … … 112 118 113 119 /** Set clock */ 114 //void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.signal();}115 void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.broadcast();;}120 void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.signal();} 121 //void set(const GSM::Time& wTime) { ScopedLock lock(mLock); mClock = wTime; updateSignal.broadcast();;} 116 122 117 123 /** Increment clock */ 118 //void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.signal();}119 void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.broadcast();}124 void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.signal();} 125 //void incTN() { ScopedLock lock(mLock); mClock.incTN(); updateSignal.broadcast();} 120 126 121 127 /** Get clock value */ … … 189 195 int wRadioOversampling = SAMPSPERSYM, 190 196 int wTransceiverOversampling = SAMPSPERSYM, 197 bool wLoadTest = false, 198 unsigned int wNumARFCNS = 1, 191 199 GSM::Time wStartTime = GSM::Time(0)); 192 200 -
openbts/trunk/TransceiverRAD1/rnrad1Core.cpp
r2242 r3689 75 75 // we get EPIPE if the firmware stalls the endpoint. 76 76 if (ret != LIBUSB_ERROR_PIPE) { 77 LOG( ALERT) << "libusb_control_transfer failed: " << _get_usb_error_str(ret);77 LOG(ERR) << "libusb_control_transfer failed: " << _get_usb_error_str(ret); 78 78 } 79 79 } -
openbts/trunk/TransceiverRAD1/runTransceiver.cpp
r3141 r3689 67 67 gLogInit("transceiver",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7); 68 68 69 int numARFCN=1; 70 if (argc>1) numARFCN = atoi(argv[1]); 71 72 #ifdef SINGLEARFCN 73 numARFCN=1; 74 #endif 75 69 76 srandom(time(NULL)); 70 77 71 78 int mOversamplingRate = 1; 79 switch(numARFCN) { 80 81 case 1: 82 mOversamplingRate = 1; 83 break; 84 case 2: 85 mOversamplingRate = 6; 86 break; 87 case 3: 88 mOversamplingRate = 8; 89 break; 90 case 4: 91 mOversamplingRate = 12; 92 break; 93 case 5: 94 mOversamplingRate = 16; 95 break; 96 default: 97 break; 98 } 99 //int mOversamplingRate = numARFCN/2 + numARFCN; 100 //mOversamplingRate = 15; //mOversamplingRate*2; 101 //if ((numARFCN > 1) && (mOversamplingRate % 2)) mOversamplingRate++; 72 102 RAD1Device *usrp = new RAD1Device(mOversamplingRate*1625.0e3/6.0); 103 //DummyLoad *usrp = new DummyLoad(mOversamplingRate*1625.0e3/6.0); 73 104 usrp->make(); 74 105 75 RadioInterface* radio = new RadioInterface(usrp,3,SAMPSPERSYM,mOversamplingRate,false); 76 Transceiver *trx = new Transceiver(5700,"127.0.0.1",SAMPSPERSYM,GSM::Time(2,0),radio); 106 RadioInterface* radio = new RadioInterface(usrp,3,SAMPSPERSYM,mOversamplingRate,false,numARFCN); 107 Transceiver *trx = new Transceiver(5700,"127.0.0.1",SAMPSPERSYM,GSM::Time(2,0),radio, 108 numARFCN,mOversamplingRate,false); 77 109 trx->receiveFIFO(radio->receiveFIFO()); 78 110 111 /* 112 signalVector *gsmPulse = generateGSMPulse(2,1); 113 BitVector normalBurstSeg = "0000101010100111110010101010010110101110011000111001101010000"; 114 BitVector normalBurst(BitVector(normalBurstSeg,gTrainingSequence[0]),normalBurstSeg); 115 signalVector *modBurst = modulateBurst(normalBurst,*gsmPulse,8,1); 116 signalVector *modBurst9 = modulateBurst(normalBurst,*gsmPulse,9,1); 117 signalVector *interpolationFilter = createLPF(0.6/mOversamplingRate,6*mOversamplingRate,1); 118 signalVector totalBurst1(*modBurst,*modBurst9); 119 signalVector totalBurst2(*modBurst,*modBurst); 120 signalVector totalBurst(totalBurst1,totalBurst2); 121 scaleVector(totalBurst,usrp->fullScaleInputValue()); 122 double beaconFreq = -1.0*(numARFCN-1)*200e3; 123 signalVector finalVec(625*mOversamplingRate); 124 for (int j = 0; j < numARFCN; j++) { 125 signalVector *frequencyShifter = new signalVector(625*mOversamplingRate); 126 frequencyShifter->fill(1.0); 127 frequencyShift(frequencyShifter,frequencyShifter,2.0*M_PI*(beaconFreq+j*400e3)/(1625.0e3/6.0*mOversamplingRate)); 128 signalVector *interpVec = polyphaseResampleVector(totalBurst,mOversamplingRate,1,interpolationFilter); 129 multVector(*interpVec,*frequencyShifter); 130 addVector(finalVec,*interpVec); 131 } 132 signalVector::iterator itr = finalVec.begin(); 133 short finalVecShort[2*finalVec.size()]; 134 short *shortItr = finalVecShort; 135 while (itr < finalVec.end()) { 136 *shortItr++ = (short) (itr->real()); 137 *shortItr++ = (short) (itr->imag()); 138 itr++; 139 } 140 usrp->loadBurst(finalVecShort,finalVec.size()); 141 */ 79 142 trx->start(); 80 143 //int i = 0; -
openbts/trunk/TransceiverRAD1/sigProcLib.cpp
r2242 r3689 600 600 //memset(staticBurst,0,sizeof(complex)*burstSize); 601 601 modBurst.fill(0.0); 602 //modBurst.fill(1.0); 602 603 signalVector::iterator modBurstItr = modBurst.begin(); 603 604
![(please configure the [header_logo] section in trac.ini)](http://wush.net/trac/rangepublic/raw-attachment/wiki/WikiStart/PublicReleaseLogo.png)
