Changeset 3689

Show
Ignore:
Timestamp:
05/30/2012 07:05:17 PM (13 months ago)
Author:
kurtis.heimerl
Message:

Adding MultiARFCN support to RAD1 radio.

Location:
openbts/trunk/TransceiverRAD1
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • openbts/trunk/TransceiverRAD1/RAD1Device.h

    r2242 r3689  
    125125  static const unsigned TEST = 0;  // bit 19 
    126126  static const unsigned LDP = 1;   // bit 18 
    127   static const unsigned ABP = 0;   // bit 17,16  3ns 
     127  static const unsigned ABP = 2;   // bit 17,16   6ns, 0 = 3ns 
    128128   
    129129  // N-Register Common Values 
     
    132132  // Control Register Common Values 
    133133  static const unsigned PD = 0;    // bits 21,20   Normal operation 
    134   static const unsigned PL = 2;    // bits 13,12   7.5mA, -6dbm 
     134  static const unsigned PL = 1;    // bits 13,12   7.5mA, -6dbm 
    135135  static const unsigned MTLD = 1;  // bit 11       enabled 
    136136  static const unsigned CPG = 0;   // bit 10       CP setting 1 
     
    139139  static const unsigned MUXOUT = 1;// bits 7:5     Digital Lock Detect 
    140140  static const unsigned CR = 0;    // bit 4        Normal 
    141   static const unsigned PC = 2;    // bits 3,2     Core power 15mA 
     141  static const unsigned PC = 0;    // bits 3,2     Core power 15mA 
    142142 
    143143  // ATR register value 
  • openbts/trunk/TransceiverRAD1/Transceiver.cpp

    r3126 r3689  
    4040                         int wSamplesPerSymbol, 
    4141                         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) 
    4647{ 
    4748  //GSM::Time startTime(0,0); 
    4849  //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  } 
    5562 
    5663  mSamplesPerSymbol = wSamplesPerSymbol; 
     
    6168  mLatencyUpdateTime = startTime; 
    6269  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"; 
    6477 
    6578  // generate pulse and setup up signal processing library 
     
    7790                                           mSamplesPerSymbol); 
    7891    scaleVector(*modBurst,txFullScale); 
    79     fillerModulus[i]=26; 
     92    fillerModulus[i] = 26; 
    8093    for (int j = 0; j < 102; j++) { 
    8194      fillerTable[j][i] = new signalVector(*modBurst); 
    8295    } 
    8396    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    } 
    89140  } 
    90141 
     
    93144  mRxFreq = 0.0; 
    94145  mPower = -10; 
    95   mEnergyThreshold = 5.0; // based on empirical data 
    96   prevFalseDetectionTime = startTime; 
     146 
     147  mControlLock.unlock(); 
     148  mTransmitPriorityQueueLock.unlock(); 
     149 
    97150} 
    98151 
     
    107160void Transceiver::addRadioVector(BitVector &burst, 
    108161                                 int RSSI, 
    109                                  GSM::Time &wTime) 
     162                                 GSM::Time &wTime, 
     163                                 int ARFCN) 
    110164{ 
    111165  // modulate and stick into queue  
     
    113167                                         8 + (wTime.TN() % 4 == 0), 
    114168                                         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 
    117189  mTransmitPriorityQueue.write(newVec); 
    118190 
     
    151223    // (It might be an idle pattern.) 
    152224    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; 
    158235  } 
    159236   
     
    161238  int modFN = nowTime.FN() % fillerModulus[nowTime.TN()]; 
    162239 
     240  bool addFiller = true; 
     241  radioVector *sendVec = NULL; 
     242 
    163243  // 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(); 
    177272 
    178273  // 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; 
    184277 
    185278} 
     
    187280void Transceiver::setModulus(int timeslot) 
    188281{ 
    189   switch (mChanType[timeslot]) { 
     282 
     283  switch (mChanType[0][timeslot]) { 
    190284  case NONE: 
    191285  case I: 
     
    210304 
    211305 
    212 Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime) 
     306CorrType Transceiver::expectedCorrType(GSM::Time currTime, int ARFCN) 
    213307{ 
    214308   
     
    216310  unsigned burstFN = currTime.FN(); 
    217311 
    218   switch (mChanType[burstTN]) { 
     312  switch (mChanType[ARFCN][burstTN]) { 
    219313  case NONE: 
    220314    return OFF; 
     
    274368} 
    275369     
    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  
     370void 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(); 
    288379  int timeslot = rxBurst->time().TN(); 
    289380 
    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                                   &amplitude, 
    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                               &amplitude, 
    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  } 
    412395 
    413396  delete rxBurst; 
    414  
    415   return burst; 
    416397} 
    417398 
    418399void Transceiver::start() 
    419400{ 
    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  } 
    421407} 
    422408 
     
    429415 
    430416   
    431 void Transceiver::driveControl() 
     417void Transceiver::driveControl(unsigned ARFCN) 
    432418{ 
    433419 
     
    439425  buffer[0] = '\0'; 
    440426  
    441   msgLen = mControlSocket.read(buffer); 
     427  msgLen = mControlSocket[ARFCN]->read(buffer); 
     428 
     429  mControlLock.lock(); 
    442430 
    443431  if (msgLen < 1) { 
     432    mControlLock.unlock(); 
    444433    return; 
    445434  } 
     
    454443 
    455444  if (strcmp(cmdcheck,"CMD")!=0) { 
    456     LOG(WARNING) << "bogus message on control interface"; 
     445    LOG(ERR) << "bogus message on control interface"; 
     446    mControlLock.unlock(); 
    457447    return; 
    458448  } 
     
    473463        mPower = -20; 
    474464        mRadioInterface->start(); 
     465 
     466        // Start radio interface threads. 
     467        writeClockInterface(); 
    475468        generateRACHSequence(*gsmPulse,mSamplesPerSymbol); 
    476469 
    477         // Start radio interface threads. 
     470        mRFIFOServiceLoopThread->start((void * (*)(void*))RFIFOServiceLoopAdapter,(void*) this); 
    478471        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 
    481486 
    482487        mOn = true; 
     
    485490  } 
    486491  else if (strcmp(command,"SETMAXDLY")==0) { 
     492    // FIXME -- Use the configuration table instead. 
    487493    //set expected maximum time-of-arrival 
    488494    int maxDelay; 
     
    492498  } 
    493499  else if (strcmp(command,"SETRXGAIN")==0) { 
     500    // FIXME -- Use the configuration table instead. 
    494501    //set expected maximum time-of-arrival 
    495502    int newGain; 
     
    499506  } 
    500507  else if (strcmp(command,"NOISELEV")==0) { 
     508    // FIXME -- Use the status table instead. 
    501509    if (mOn) { 
    502510      sprintf(response,"RSP NOISELEV 0 %d", 
    503               (int) round(20.0*log10(rxFullScale/mEnergyThreshold))); 
     511              (int) round(20.0*log10(rxFullScale/mDemodulators[0]->getEnergyThreshold()))); 
    504512    } 
    505513    else { 
     
    514522      sprintf(response,"RSP SETPOWER 1 %d",dbPwr); 
    515523    else { 
    516       mPower = dbPwr; 
    517       mRadioInterface->setPowerAttenuation(dbPwr); 
     524      if (ARFCN==0) { 
     525        mPower = dbPwr; 
     526        mRadioInterface->setPowerAttenuation(dbPwr + gConfig.getNum("TRX.TxAttenOffset")); 
     527      } 
    518528      sprintf(response,"RSP SETPOWER 0 %d",dbPwr); 
    519529    } 
    520530  } 
    521531  else if (strcmp(command,"ADJPOWER")==0) { 
     532    // FIXME -- Use the configuration table instead. 
    522533    // adjust power in dB steps 
    523534    int dbStep; 
     
    526537      sprintf(response,"RSP ADJPOWER 1 %d",mPower); 
    527538    else { 
    528       mPower += dbStep; 
     539      if (ARFCN==0)  
     540        mPower += dbStep; 
    529541      sprintf(response,"RSP ADJPOWER 0 %d",mPower); 
    530542    } 
    531543  } 
    532 #define FREQOFFSET 0//11.2e3 
    533544  else if (strcmp(command,"RXTUNE")==0) { 
    534545    // tune receiver 
    535546    int freqKhz; 
    536547    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"))) { 
    539550       LOG(ALERT) << "RX failed to tune"; 
    540551       sprintf(response,"RSP RXTUNE 1 %d",freqKhz); 
     
    548559    sscanf(buffer,"%3s %s %d",cmdcheck,command,&freqKhz); 
    549560    //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"))) { 
    552563       LOG(ALERT) << "TX failed to tune"; 
    553564       sprintf(response,"RSP TXTUNE 1 %d",freqKhz); 
     
    563574      sprintf(response,"RSP SETTSC 1 %d",TSC); 
    564575    else { 
    565       mTSC = TSC; 
    566       generateMidamble(*gsmPulse,mSamplesPerSymbol,TSC); 
     576      if (ARFCN==0) { 
     577        mTSC = TSC; 
     578        generateMidamble(*gsmPulse,mSamplesPerSymbol,TSC); 
     579      } 
    567580      sprintf(response,"RSP SETTSC 0 %d",TSC); 
    568581    } 
     
    573586    int  timeslot; 
    574587    sscanf(buffer,"%3s %s %d %d",cmdcheck,command,&timeslot,&corrCode); 
     588    //sscanf(buffer,"%3s %s %d %d %d",cmdcheck,command,&timeslot,&corrCode,&ARFCN); 
    575589    if ((timeslot < 0) || (timeslot > 7)) { 
    576       LOG(WARNING) << "bogus message on control interface"; 
     590      LOG(ERR) << "bogus message on control interface"; 
    577591      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    } 
    584602  } 
    585603  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 
     614bool Transceiver::driveTransmitPriorityQueue(unsigned ARFCN)  
     615{ 
     616 
     617 
     618#if 1  
    596619  char buffer[gSlotLen+50]; 
    597620 
    598621  // check data socket 
    599   size_t msgLen = mDataSocket.read(buffer); 
     622  size_t msgLen = mDataSocket[ARFCN]->read(buffer); 
     623 
     624  mTransmitPriorityQueueLock.lock(); 
    600625 
    601626  if (msgLen!=gSlotLen+1+4+1) { 
    602627    LOG(ERR) << "badly formatted packet on GSM->TRX interface"; 
     628    mTransmitPriorityQueueLock.unlock(); 
    603629    return false; 
    604630  } 
     
    626652   
    627653  // periodically update GSM core clock 
    628   LOG(DEBUG) << "mTransmitDeadlineClock " << mTransmitDeadlineClock 
    629                 << " mLastClockUpdateTime " << mLastClockUpdateTime; 
     654  //LOG(DEBUG) << "mTransmitDeadlineClock " << mTransmitDeadlineClock 
     655  //            << " mLastClockUpdateTime " << mLastClockUpdateTime; 
    630656  if (mTransmitDeadlineClock > mLastClockUpdateTime + GSM::Time(216,0)) 
    631657    writeClockInterface(); 
    632658 
    633659 
    634   LOG(DEBUG) << "rcvd. burst at: " << GSM::Time(frameNum,timeSlot); 
     660  //LOG(DEBUG) << "rcvd. burst at: " << GSM::Time(frameNum,timeSlot); 
    635661   
    636662  int RSSI = (int) buffer[5]; 
     
    643669  GSM::Time currTime = GSM::Time(frameNum,timeSlot); 
    644670   
    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 
    648695 
    649696  return true; 
     
    652699} 
    653700  
    654 void Transceiver::driveReceiveFIFO()  
    655 { 
    656  
     701void Transceiver::driveReceiveFIFO() 
     702{ 
     703  mRadioInterface->driveReceiveRadio(); 
     704 
     705  pullRadioVector(); 
     706} 
     707 
     708 
     709void 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 
     763void 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   
     778void *FIFOServiceLoopAdapter(Transceiver *transceiver) 
     779{ 
     780  while (1) { 
     781    //transceiver->driveReceiveFIFO(); 
     782    transceiver->driveTransmitFIFO(); 
     783    pthread_testcancel(); 
     784  } 
     785  return NULL; 
     786} 
     787 
     788void *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 
     801void *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 
     812void *DemodServiceLoopAdapter(Demodulator *demodulator) 
     813{ 
     814  while(1) { 
     815    demodulator->driveDemod(); 
     816    pthread_testcancel(); 
     817  } 
     818  return NULL; 
     819} 
     820 
     821void *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 
     841Demodulator::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 
     873void Demodulator::driveDemod(bool wSingleARFCN)  
     874{ 
     875 
     876  //LOG(DEBUG) << "calling driveDemod "; 
     877 
     878  radioVector *demodBurst = NULL; 
    657879  SoftVector *rxBurst = NULL; 
    658880  int RSSI; 
     
    660882  GSM::Time burstTime; 
    661883 
    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); 
    665902 
    666903  if (rxBurst) {  
    667904 
    668905    LOG(DEBUG) << "burst parameters: " 
     906          << " ARFCN: " << mARFCN 
    669907          << " time: " << burstTime 
    670908          << " RSSI: " << RSSI 
     
    687925    delete rxBurst; 
    688926 
    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 
     932SoftVector *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                                  &amplitude, 
     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]; 
    7231018      } 
    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                              &amplitude, 
     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  
    4141//#define TRANSMIT_LOGGING 1 
    4242 
     43#define MAXARFCN 5 
     44 
     45 
     46/** Codes for burst types of received bursts*/ 
     47typedef 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 
     54class Demodulator; 
     55class Transceiver; 
     56 
     57typedef struct ThreadStruct { 
     58   Transceiver *trx; 
     59   unsigned ARFCN; 
     60} ThreadStruct; 
     61 
    4362/** The Transceiver class, responsible for physical layer of basestation */ 
    4463class Transceiver { 
     
    4968  GSM::Time mLatencyUpdateTime;   ///< last time latency was updated 
    5069 
    51   UDPSocket mDataSocket;          ///< socket for writing to/reading from GSM core 
    52   UDPSocket mControlSocket;       ///< socket for writing/reading control commands from GSM core 
     70  UDPSocket *mDataSocket[MAXARFCN];       ///< socket for writing to/reading from GSM core 
     71  UDPSocket *mControlSocket[MAXARFCN];    ///< socket for writing/reading control commands from GSM core 
    5372  UDPSocket mClockSocket;         ///< socket for writing clock updates to GSM core 
    5473 
     
    5675  VectorFIFO*  mTransmitFIFO;     ///< radioInterface FIFO of transmit bursts  
    5776  VectorFIFO*  mReceiveFIFO;      ///< radioInterface FIFO of receive bursts  
     77  VectorFIFO*  mDemodFIFO[MAXARFCN]; 
    5878 
    5979  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 
    6284 
    6385  GSM::Time mTransmitDeadlineClock;       ///< deadline for pushing bursts into transmit FIFO  
    6486  GSM::Time mLastClockUpdateTime;         ///< last time clock update was sent up to core 
     87  GSM::Time mStartTime; 
    6588 
    6689  RadioInterface *mRadioInterface;        ///< associated radioInterface object 
    6790  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; 
    7897 
    7998  /** Codes for channel combinations */ 
     
    100119  void addRadioVector(BitVector &burst, 
    101120                      int RSSI, 
    102                       GSM::Time &wTime); 
     121                      GSM::Time &wTime, 
     122                      int ARFCN); 
    103123 
    104124  /** Push modulated burst into transmit FIFO corresponding to a particular timestamp */ 
     
    106126 
    107127  /** 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); 
    111129    
    112130  /** Set modulus for specific timeslot */ 
    113131  void setModulus(int timeslot); 
    114132 
    115   /** return the expected burst type for the specified timestamp */ 
    116   CorrType expectedCorrType(GSM::Time currTime); 
    117  
    118133  /** send messages over the clock socket */ 
    119134  void writeClockInterface(void); 
     
    124139 
    125140  bool mOn;                            ///< flag to indicate that transceiver is powered on 
    126   ChannelCombination mChanType[8];     ///< channel types for all timeslots 
     141  ChannelCombination mChanType[MAXARFCN][8];     ///< channel types for all timeslots 
    127142  double mTxFreq;                      ///< the transmit frequency 
    128143  double mRxFreq;                      ///< the receive frequency 
    129144  int mPower;                          ///< the transmit power in dB 
    130145  unsigned mTSC;                       ///< the midamble sequence code 
    131   double mEnergyThreshold;             ///< threshold to determine if received data is potentially a GSM burst 
    132   GSM::Time prevFalseDetectionTime;    ///< last timestamp of a false energy detection 
    133146  int fillerModulus[8];                ///< modulus values of all timeslots, in frames 
    134147  signalVector *fillerTable[102][8];   ///< table of modulated filler waveforms for all timeslots 
    135148  unsigned mMaxExpectedDelay;            ///< maximum expected time-of-arrival offset in GSM symbols 
    136149 
    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 
    144162 
    145163public: 
     
    156174              int wSamplesPerSymbol, 
    157175              GSM::Time wTransmitLatency, 
    158               RadioInterface *wRadioInterface); 
     176              RadioInterface *wRadioInterface, 
     177              unsigned int wNumARFCNs, 
     178              unsigned int wOversamplingRate, 
     179              bool wLoadTest); 
    159180    
    160181  /** Destructor */ 
     
    164185  void start(); 
    165186 
     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 
    166192  /** attach the radioInterface receive FIFO */ 
    167193  void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;} 
     
    170196  void transmitFIFO(VectorFIFO *wFIFO) { mTransmitFIFO = wFIFO;} 
    171197 
     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; } 
    172211 
    173212protected: 
     
    180219 
    181220  /** drive handling of control messages from GSM core */ 
    182   void driveControl(); 
     221  void driveControl(unsigned ARFCN); 
    183222 
    184223  /** 
     
    186225    @return true if a burst was transferred successfully 
    187226  */ 
    188   bool driveTransmitPriorityQueue(); 
     227  bool driveTransmitPriorityQueue(unsigned ARFCN); 
    189228 
    190229  friend void *FIFOServiceLoopAdapter(Transceiver *); 
    191230 
    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 *); 
    195236 
    196237  void reset(); 
     
    200241void *FIFOServiceLoopAdapter(Transceiver *); 
    201242 
     243void *RFIFOServiceLoopAdapter(Transceiver *); 
     244 
    202245/** control message handler thread loop */ 
    203 void *ControlServiceLoopAdapter(Transceiver *); 
     246void *ControlServiceLoopAdapter(ThreadStruct *); 
    204247 
    205248/** transmit queueing thread loop */ 
    206 void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *); 
    207  
     249void *TransmitPriorityQueueServiceLoopAdapter(ThreadStruct *); 
     250 
     251class 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 
     300void *DemodServiceLoopAdapter(Demodulator *); 
  • openbts/trunk/TransceiverRAD1/radioInterface.cpp

    r2242 r3689  
    7272                               int wRadioOversampling, 
    7373                               int wTransceiverOversampling, 
     74                               bool wLoadTest, 
     75                               unsigned int wNumARFCNs, 
    7476                               GSM::Time wStartTime) 
    7577 
     
    8688  mClock.set(wStartTime); 
    8789  powerScaling = 1.0; 
     90  mNumARFCNs = wNumARFCNs; 
     91 
     92  loadTest = wLoadTest; 
    8893} 
    8994 
     
    237242  mOn = true; 
    238243 
     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 
    239272} 
    240273 
     
    288321    if (rcvClock.FN() >= 0) { 
    289322      //LOG(DEBUG) << "FN: " << rcvClock.FN(); 
     323      int dummyARFCN = 0; 
    290324      radioVector *rxBurst = NULL; 
    291325      if (!loadTest) 
    292         rxBurst = new radioVector(rxVector,tmpTime); 
     326        rxBurst = new radioVector(rxVector,tmpTime,dummyARFCN); 
    293327      else { 
    294328        if (tN % 4 == 0) 
    295           rxBurst = new radioVector(*finalVec9,tmpTime); 
     329          rxBurst = new radioVector(*finalVec9,tmpTime,dummyARFCN); 
    296330        else 
    297           rxBurst = new radioVector(*finalVec,tmpTime);  
     331          rxBurst = new radioVector(*finalVec,tmpTime,dummyARFCN);  
    298332      } 
    299333      mReceiveFIFO.put(rxBurst);  
  • openbts/trunk/TransceiverRAD1/radioInterface.h

    r2305 r3689  
    4141 
    4242  GSM::Time mTime;   ///< the burst's GSM timestamp  
     43  int mARFCN; 
    4344 
    4445public: 
    4546  /** constructor */ 
    4647  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){}; 
    4850 
    4951  /** timestamp read and write operators */ 
    5052  GSM::Time time() const { return mTime;} 
    5153  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;} 
    5258 
    5359  /** comparison operator, used for sorting */ 
     
    112118 
    113119  /** 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();;} 
    116122 
    117123  /** 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();} 
    120126 
    121127  /** Get clock value */ 
     
    189195                 int wRadioOversampling = SAMPSPERSYM, 
    190196                 int wTransceiverOversampling = SAMPSPERSYM, 
     197                 bool wLoadTest = false, 
     198                 unsigned int wNumARFCNS = 1, 
    191199                 GSM::Time wStartTime = GSM::Time(0)); 
    192200     
  • openbts/trunk/TransceiverRAD1/rnrad1Core.cpp

    r2242 r3689  
    7575    // we get EPIPE if the firmware stalls the endpoint. 
    7676    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); 
    7878    } 
    7979  } 
  • openbts/trunk/TransceiverRAD1/runTransceiver.cpp

    r3141 r3689  
    6767  gLogInit("transceiver",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7); 
    6868 
     69  int numARFCN=1; 
     70  if (argc>1) numARFCN = atoi(argv[1]); 
     71 
     72#ifdef SINGLEARFCN 
     73  numARFCN=1; 
     74#endif 
     75 
    6976  srandom(time(NULL)); 
    7077 
    7178  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++; 
    72102  RAD1Device *usrp = new RAD1Device(mOversamplingRate*1625.0e3/6.0); 
     103  //DummyLoad *usrp = new DummyLoad(mOversamplingRate*1625.0e3/6.0); 
    73104  usrp->make();  
    74105 
    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); 
    77109  trx->receiveFIFO(radio->receiveFIFO()); 
    78110 
     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*/ 
    79142  trx->start(); 
    80143  //int i = 0; 
  • openbts/trunk/TransceiverRAD1/sigProcLib.cpp

    r2242 r3689  
    600600  //memset(staticBurst,0,sizeof(complex)*burstSize); 
    601601  modBurst.fill(0.0); 
     602  //modBurst.fill(1.0); 
    602603  signalVector::iterator modBurstItr = modBurst.begin(); 
    603604