A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
pu-model.cc
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * Author: Abdulla K. Al-Ali <abdulla.alali@qu.edu.qa>
16  */
17 
18 #include "pu-model.h"
19 
20 NS_LOG_COMPONENT_DEFINE ("CogPUModel");
21 
22 // PU model class
23 // Implementation of the model of PU activity for CRAHNs
24 
25 namespace ns3 {
26 
27 TypeId
28 PUModel::GetTypeId (void)
29 {
30  static TypeId tid = TypeId ("ns3::PUModel")
31  .SetParent<Object> ()
32  .AddConstructor<PUModel> ()
33  ;
34  return tid;
35 }
36 
37 
38 // PUmodel Initializer
39 PUModel::PUModel() {
40  m_numberPus_=0;
41 }
42 
43 // ReadData: Read the content of the current pu map file and saves the information on the PU data structure
44 void
45 PUModel::ReadData(char* dir) {
46 
47  FILE* fd;
48 
49  fd=fopen(dir,"rt");
50 
51  NS_LOG_DEBUG ("Reading PU Data from File: " << dir);
52 
53 
54  if (fd==NULL) {
55  NS_FATAL_ERROR("Can't open file " << dir);
56  }
57 
58  // The first line contains the following entry:
59  // <# number_of_PU>
60  fscanf(fd,"%d",&m_numberPus_);
61 
62  if (ferror(fd)) {
63  NS_FATAL_ERROR ("Can't read PU number Information from file " << dir);
64  }
65 
66 
67  if (IO_DEBUG)
68  NS_LOG_DEBUG ("[READING MAP FILE] #PU users: " << m_numberPus_);
69 
70 
71  if (m_numberPus_> MAX_PU_USERS)
72  NS_LOG_ERROR ("Too many PU in the file. Max allowed is " << MAX_PU_USERS);
73 
74  // The second section contains the following entry:
75  // <PU_id, x_loc, y_loc, x_loc_receiver, y_loc_receiver, alpha, beta, tx_range>
76 
77  for (int i=0; i< m_numberPus_; i++) {
78  int channel;
79  float x,y,x2,y2;
80  float alpha, beta;
81  float range;
82 
83  fscanf(fd,"%d %f %f %f %f %e %e %f",&channel,&x,&y,&x2,&y2,&alpha,&beta,&range);
84 
85  if (ferror(fd))
86  NS_LOG_ERROR ("Can't read PU number Information from file " << dir);
87 
88 
89  NS_LOG_DEBUG ("[READING MAP FILE] #PU Location: channel: " << channel << " x="
90  << x << " y=" << y << " #PU Receiver: x=" << x2 << " y=" << y2 << " ALPHA: "
91  << alpha << " BETA: " << beta << " TX RANGE: " << range );
92 
93 
94  m_puData[i].main_channel=channel;
95  m_puData[i].x_loc=x;
96  m_puData[i].y_loc=y;
97  m_puData[i].x_loc_receiver=x2;
98  m_puData[i].y_loc_receiver=y2;
99  m_puData[i].alpha=alpha;
100  m_puData[i].beta=beta;
101  m_puData[i].radius=range;
102  m_puData[i].interference=0.0;
103  }
104 
105 
106 
107  // The third section contains the following entry:
108  // <arrival_PU_0, ..,arrival_PU_n>
109  // <departure_PU_0, ..,departure_PU_n>
110 
111  for (int j=0; j< m_numberPus_; j++) {
112  int arrivals=0;
113  int departures=0;
114  int number=0;
115 
116  fscanf(fd,"%d",&number);
117 
118  if (ferror(fd))
119  NS_LOG_ERROR ("Can't read PU number DATA Information from file " << dir);
120 
121  NS_LOG_DEBUG ("[READING MAP FILE] #PU ON times: " << number);
122 
123  if (number>MAX_PU_DATA_ENTRY)
124  NS_FATAL_ERROR("Too many PU DATA ON times in the file. Max allowed is " << MAX_PU_DATA_ENTRY << " " << number);
125 
126  m_puData[j].number_data=number;
127 
128  for (int i=0; i< (2*number); i++) {
129  float time;
130  fscanf(fd," %f ",&time);
131  if (i%2==0) {
132  // Reading the arrival time
133  m_puData[j].arrival_time[arrivals]=Seconds(time);
134  arrivals++;
135  NS_LOG_DEBUG ("[READING MAP FILE] #PU arrival: " << j << " " << time);
136  } else {
137  // Reading the departure time
138  m_puData[j].departure_time[departures]=Seconds(time);
139  departures++;
140  NS_LOG_DEBUG ("[READING MAP FILE] #PU departure: " << j << time);
141 
142 
143  }
144 
145  m_puData[j].detected[arrivals]=false;
146 
147  }
148  }
149 }
150 
151 // is_PU_active: Check if a PU is active in the time interval [timeNow, timeNow + ts]
152 bool
153 PUModel::IsPuActive(Time timeNow, Time ts, double x, double y, int channel) {
154 
155  bool active=false;
156 
157  for (int i=0; i< m_numberPus_; i++) {
158  if ((m_puData[i].main_channel==channel) && (Distance(x,y,i) <=m_puData[i].radius))
159  active=CheckActive(timeNow,ts,i);
160 
161  if (active) {
162  return true;
163  }
164 
165  }
166 
167  return false;
168 
169 }
170 
171 
172 
173 
174 
175 // check:active: Check if a PU is transmitting in the interval [timeNow, timeNow + ts]
176 bool
177 PUModel::CheckActive(Time timeNow, Time ts, int channel) {
178 
179  Time endTime=timeNow+ts;
180  int number=m_puData[channel].number_data;
181  double active=false;
182 
183  for (int i=0; i<number; i++) {
184 
185  // Check if there is an overlapping with the current PU activity
186  if( (m_puData[channel].arrival_time[i]>=timeNow && m_puData[channel].departure_time[i]>=endTime && m_puData[channel].arrival_time[i]<=endTime) || (m_puData[channel].arrival_time[i]<=timeNow && m_puData[channel].departure_time[i]>=endTime) ||
187  (m_puData[channel].arrival_time[i]<=timeNow && m_puData[channel].departure_time[i]>=timeNow && m_puData[channel].departure_time[i]<=endTime)) {
188 
189  active=true;
190  m_puData[channel].detected[i]=true;
191 
192  }
193 
194  // If there is on overlapping, then jump out from the cycle
195  if (active || m_puData[channel].arrival_time[i]>endTime)
196  i=number;
197  }
198 
199  return(active);
200 
201 }
202 
203 
204 
205 /*
206  * this function checks if PU is active in a time period. This is useful for our TFRC implementation
207  * where we assume that the database returns only PUs that are affecting the chain
208  */
209 bool
210 PUModel::CheckActive(Time timeNow, Time ts) {
211 
212 
213  Time endTime=timeNow+ts;
214  double active=false;
215 
216  for (int j=0; j<m_numberPus_; j++) {
217  for (int i=0; i<m_puData[j].number_data; i++) {
218 
219  // Check if there is an overlapping with the current PU activity
220  if( (m_puData[j].arrival_time[i]>=timeNow && m_puData[j].departure_time[i]>=endTime && m_puData[j].arrival_time[i]<=endTime) || (m_puData[j].arrival_time[i]<=timeNow && m_puData[j].departure_time[i]>=endTime) ||
221  (m_puData[j].arrival_time[i]<=timeNow && m_puData[j].departure_time[i]>=timeNow && m_puData[j].departure_time[i]<=endTime)) {
222 
223  active=true;
224  m_puData[j].detected[i]=true;
225 
226  }
227 
228  // If there is on overlapping, then jump out from the cycle
229  if (active) {
230  i=m_puData[j].number_data;
231  j=m_numberPus_;
232  }
233  if (m_puData[j].arrival_time[i]>endTime) {
234  i=m_puData[j].number_data;
235  }
236  }
237  }
238 
239  return(active);
240 
241 }
242 
243 /*
244  * Get the next time the PU goes off.
245  * This is needed for our TFRC protocol so that it can start sending immediately at this time
246  * returns -1 if there is no PU currently
247  */
248 Time
249 PUModel::GetNextOffTime(Time timeNow) {
250 
251 
252  Time endTime=timeNow+Seconds(0.001);
253  bool active=false;
254  Time timeOff = Seconds(0);
255 
256  for (int j=0; j<m_numberPus_; j++) {
257  for (int i=0; i<m_puData[j].number_data; i++) {
258 
259  // Check if there is an overlapping with the current PU activity
260  if( (m_puData[j].arrival_time[i]>=timeNow && m_puData[j].departure_time[i]>=endTime && m_puData[j].arrival_time[i]<=endTime) || (m_puData[j].arrival_time[i]<=timeNow && m_puData[j].departure_time[i]>=endTime) ||
261  (m_puData[j].arrival_time[i]<=timeNow && m_puData[j].departure_time[i]>=timeNow && m_puData[j].departure_time[i]<=endTime)) {
262 
263  active=true;
264  m_puData[j].detected[i]=true;
265 
266  }
267 
268  // If there is on overlapping, then jump out from the cycle
269  if (active) {
270  timeOff = m_puData[j].departure_time[i];
271  NS_LOG_DEBUG ("time off: " << m_puData[j].departure_time[i] <<" i="<< i <<" and j="<< j );
272  i=m_puData[j].number_data;
273  j=m_numberPus_;
274  }
275  if (m_puData[j].arrival_time[i]>endTime) {
276  i=m_puData[j].number_data;
277  }
278  }
279  }
280 
281  return(timeOff);
282 
283 }
284 
285 
286 /**********************************************************/
287 /* DISTANCE METHODS
288  **********************************************************/
289 
290 //distance: Return the current distance from the PU transmitter on a given channel
291 double
292 PUModel::Distance(double x, double y, int channel) {
293  double dx=(x-m_puData[channel].x_loc)*(x-m_puData[channel].x_loc);
294  double dy=(y-m_puData[channel].y_loc)*(y-m_puData[channel].y_loc);
295  double dist=std::sqrt((float)(dx+dy));
296 
297  return dist;
298 }
299 
300 
301 
302 
304 double
305 PUModel::DistanceFromReceiver(double x, double y, int channel) {
306 
307  double dx=(x-m_puData[channel].x_loc_receiver)*(x-m_puData[channel].x_loc_receiver);
308  double dy=(y-m_puData[channel].y_loc_receiver)*(y-m_puData[channel].y_loc_receiver);
309  double dist=std::sqrt((float)(dx+dy));
310 
311  return dist;
312 }
313 
314 void
315 PUModel::SetPuMapFile(char * fileName)
316 {
317  ReadData(fileName);
318 }
319 
320 }
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
double DistanceFromReceiver(double x, double y, int channel)
distance_receiver: Return the current distance from the PU receiver on a given channel ...
Definition: pu-model.cc:305
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
#define NS_LOG_ERROR(msg)
Definition: log.h:237