00001 #include "PhyUtils.h"
00002
00003 using namespace std;
00004
00005 void RadioStateAnalogueModel::filterSignal(Signal& s)
00006 {
00007 simtime_t start = s.getSignalStart();
00008 simtime_t end = start + s.getSignalLength();
00009
00010 RSAMMapping* attMapping = new RSAMMapping(this, start, end);
00011 s.addAttenuation(attMapping);
00012 }
00013
00014 void RadioStateAnalogueModel::cleanUpUntil(simtime_t t)
00015 {
00016
00017 assert(!radioStateAttenuation.empty());
00018
00019
00020
00021
00022 if ( t <= radioStateAttenuation.front().getTime() )
00023 {
00024 return;
00025 }
00026
00027
00028
00029
00030 if ( t > radioStateAttenuation.back().getTime() )
00031 {
00032 ListEntry lastEntry = radioStateAttenuation.back();
00033 radioStateAttenuation.clear();
00034 radioStateAttenuation.push_back(lastEntry);
00035 return;
00036 }
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 std::list<ListEntry>::iterator it;
00047 it = lower_bound(radioStateAttenuation.begin(), radioStateAttenuation.end(), t);
00048
00049
00050
00051 if ( it->getTime() == t )
00052 {
00053 radioStateAttenuation.erase(radioStateAttenuation.begin(), it);
00054 return;
00055 }
00056
00057
00058
00059 it--;
00060
00061 it->setTime(t);
00062 radioStateAttenuation.erase(radioStateAttenuation.begin(), it);
00063
00064 }
00065
00066 void RadioStateAnalogueModel::writeRecvEntry(simtime_t time, double value)
00067 {
00068
00069 assert( (radioStateAttenuation.empty()) || (time >= radioStateAttenuation.back().getTime()) );
00070
00071 radioStateAttenuation.push_back(ListEntry(time, value));
00072
00073 if (!currentlyTracking)
00074 {
00075 cleanUpUntil(time);
00076
00077 assert(radioStateAttenuation.back().getTime() == time);
00078 }
00079 }
00080
00081
00082
00083
00084 Radio::Radio(int numRadioStates,
00085 bool recordStats,
00086 int initialState,
00087 double minAtt, double maxAtt,
00088 int currentChannel, int nbChannels):
00089 state(initialState), nextState(initialState),
00090 numRadioStates(numRadioStates),
00091 minAtt(minAtt), maxAtt(maxAtt),
00092 rsam(mapStateToAtt(initialState)),
00093 currentChannel(currentChannel), nbChannels(nbChannels)
00094 {
00095 assert(nbChannels > 0);
00096 assert(currentChannel > -1);
00097 assert(currentChannel < nbChannels);
00098
00099 radioStates.setName("RadioState");
00100 radioStates.setEnabled(recordStats);
00101 radioStates.record(initialState);
00102 radioChannels.setName("RadioChannel");
00103 radioChannels.setEnabled(recordStats);
00104 radioChannels.record(currentChannel);
00105
00106
00107 swTimes = new simtime_t* [numRadioStates];
00108
00109
00110 for (int i = 0; i < numRadioStates; i++)
00111 {
00112
00113 swTimes[i] = new simtime_t[numRadioStates];
00114 }
00115
00116
00117 for (int i = 0; i < numRadioStates; i++)
00118 {
00119 for (int j = 0; j < numRadioStates; j++)
00120 {
00121 swTimes[i][j] = 0;
00122 }
00123 }
00124 }
00125
00126 Radio::~Radio()
00127 {
00128
00129 for (int i = 0; i < numRadioStates; i++)
00130 {
00131 delete[] swTimes[i];
00132 }
00133
00134 delete[] swTimes;
00135 swTimes = 0;
00136 }
00137
00138 simtime_t Radio::switchTo(int newState, simtime_t now)
00139 {
00140
00141 assert(0 <= newState && newState < numRadioStates);
00142
00143
00144 assert(newState != SWITCHING);
00145
00146
00147
00148
00149
00150
00151 if (state == SWITCHING) return -1;
00152
00153
00154
00155
00156
00157
00158 nextState = newState;
00159 int lastState = state;
00160 state = SWITCHING;
00161 radioStates.record(state);
00162
00163
00164 makeRSAMEntry(now, state);
00165
00166
00167 return swTimes[lastState][nextState];
00168 }
00169
00170 void Radio::setSwitchTime(int from, int to, simtime_t time)
00171 {
00172
00173 assert(time >= 0.0);
00174 assert(0 <= from && from < numRadioStates);
00175 assert(0 <= to && to < numRadioStates);
00176
00177
00178 assert(from != SWITCHING && to != SWITCHING);
00179
00180
00181 swTimes[from][to] = time;
00182 return;
00183 }
00184
00185 void Radio::endSwitch(simtime_t now)
00186 {
00187
00188 assert(state == SWITCHING);
00189
00190
00191 state = nextState;
00192 radioStates.record(state);
00193
00194
00195 makeRSAMEntry(now, state);
00196
00197 return;
00198 }
00199
00200
00201
00202
00203 RSAMConstMappingIterator::RSAMConstMappingIterator
00204 (const RadioStateAnalogueModel* rsam,
00205 simtime_t signalStart,
00206 simtime_t signalEnd) :
00207 rsam(rsam),
00208 signalStart(signalStart),
00209 signalEnd(signalEnd)
00210 {
00211 assert(rsam);
00212
00213 assert( !(signalStart < rsam->radioStateAttenuation.front().getTime()) );
00214
00215 jumpToBegin();
00216 }
00217
00218 void RSAMConstMappingIterator::jumpTo(const Argument& pos)
00219 {
00220
00221 simtime_t t = pos.getTime();
00222
00223 assert( !(rsam->radioStateAttenuation.empty()) &&
00224 !(t < rsam->radioStateAttenuation.front().getTime()) );
00225
00226
00227 if( t == position.getTime() )
00228 return;
00229
00230
00231 it = upper_bound(rsam->radioStateAttenuation.begin(), rsam->radioStateAttenuation.end(), t);
00232
00233 --it;
00234 position.setTime(t);
00235 setNextPosition();
00236 }
00237
00238 void RSAMConstMappingIterator::setNextPosition()
00239 {
00240 if (hasNext())
00241 {
00242 if(position.getTime() < signalStart)
00243 {
00244 nextPosition.setTime(signalStart);
00245 } else
00246 {
00247 CurrList::const_iterator it2 = it;
00248 it2++;
00249
00250 assert(it->getTime() <= position.getTime() && position.getTime() < it2->getTime());
00251
00252
00253 simtime_t preTime = MappingUtils::pre(it2->getTime());
00254
00255 if(position.getTime() == preTime) {
00256 nextPosition.setTime(it2->getTime());
00257 }
00258 else {
00259 nextPosition.setTime(preTime);
00260 }
00261 }
00262
00263 } else
00264 {
00265 nextPosition.setTime(position.getTime() + 1);
00266 }
00267
00268 }
00269
00270 void RSAMConstMappingIterator::iterateTo(const Argument& pos)
00271 {
00272
00273 simtime_t t = pos.getTime();
00274
00275
00276 assert( !(rsam->radioStateAttenuation.empty()) &&
00277 !(t < rsam->radioStateAttenuation.front().getTime()) );
00278
00279 assert( !(t < position.getTime()) );
00280
00281
00282
00283
00284
00285 if( t == position.getTime() )
00286 return;
00287
00288
00289 iterateToOverZeroSwitches(t);
00290
00291
00292 position.setTime(t);
00293 setNextPosition();
00294
00295 }
00296
00297 bool RSAMConstMappingIterator::inRange() const
00298 {
00299 simtime_t t = position.getTime();
00300 simtime_t lastEntryTime = std::max(rsam->radioStateAttenuation.back().getTime(), signalStart);
00301
00302 return signalStart <= t
00303 && t <= signalEnd
00304 && t <= lastEntryTime;
00305
00306 }
00307
00308 bool RSAMConstMappingIterator::hasNext() const
00309 {
00310 assert( !(rsam->radioStateAttenuation.empty()) );
00311
00312 CurrList::const_iterator it2 = it;
00313 if (it2 != rsam->radioStateAttenuation.end())
00314 {
00315 it2++;
00316 }
00317
00318 return position.getTime() < signalStart
00319 || (it2 != rsam->radioStateAttenuation.end() && it2->getTime() <= signalEnd);
00320 }
00321
00322 void RSAMConstMappingIterator::iterateToOverZeroSwitches(simtime_t t)
00323 {
00324 if( it != rsam->radioStateAttenuation.end() && !(t < it->getTime()) )
00325 {
00326
00327 while( it != rsam->radioStateAttenuation.end() && !(t < it->getTime()) )
00328 it++;
00329
00330
00331 it--;
00332 }
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342 double RSAMMapping::getValue(const Argument& pos) const
00343 {
00344
00345 simtime_t t = pos.getTime();
00346
00347
00348
00349 assert( !(rsam->radioStateAttenuation.empty()) &&
00350 !(t < rsam->radioStateAttenuation.front().getTime()) );
00351
00352
00353
00354
00355 std::list<RadioStateAnalogueModel::ListEntry>::const_iterator it;
00356 it = upper_bound(rsam->radioStateAttenuation.begin(), rsam->radioStateAttenuation.end(), t);
00357
00358
00359 it--;
00360
00361 return it->getValue();
00362 }
00363
00364 ConstMappingIterator* RSAMMapping::createConstIterator(const Argument& pos)
00365 {
00366 RSAMConstMappingIterator* rsamCMI
00367 = new RSAMConstMappingIterator(rsam, signalStart, signalEnd);
00368
00369 rsamCMI->jumpTo(pos);
00370
00371 return rsamCMI;
00372 }