1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
|
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
*
* Copyright (c) 1997 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Header: /cvsroot/nsnam/ns-2/mac/mac-802_11.h,v 1.30 2010/03/08 05:54:52 tom_henderson Exp $
*
* Ported from CMU/Monarch's code, nov'98 -Padma.
* wireless-mac-802_11.h
*/
#ifndef ns_mac_80211_h
#define ns_mac_80211_h
// Added by Sushmita to support event tracing (singal@nunki.usc.edu)
#include "address.h"
#include "ip.h"
#include "mac-timers.h"
#include "marshall.h"
#include <math.h>
#include <stddef.h>
#include <list>
class EventTrace;
#define GET_ETHER_TYPE(x) GET2BYTE((x))
#define SET_ETHER_TYPE(x,y) {u_int16_t t = (y); STORE2BYTE(x,&t);}
/* ======================================================================
Frame Formats
====================================================================== */
#define MAC_ProtocolVersion 0x00
#define MAC_Type_Management 0x00
#define MAC_Type_Control 0x01
#define MAC_Type_Data 0x02
#define MAC_Type_Reserved 0x03
#define MAC_Subtype_RTS 0x0B
#define MAC_Subtype_CTS 0x0C
#define MAC_Subtype_ACK 0x0D
#define MAC_Subtype_Data 0x00
#define MAC_Subtype_80211_Beacon 0x08
#define MAC_Subtype_AssocReq 0x00
#define MAC_Subtype_AssocRep 0x01
#define MAC_Subtype_Auth 0x0C
#define MAC_Subtype_ProbeReq 0x04
#define MAC_Subtype_ProbeRep 0x05
struct frame_control {
u_char fc_subtype : 4;
u_char fc_type : 2;
u_char fc_protocol_version : 2;
u_char fc_order : 1;
u_char fc_wep : 1;
u_char fc_more_data : 1;
u_char fc_pwr_mgt : 1;
u_char fc_retry : 1;
u_char fc_more_frag : 1;
u_char fc_from_ds : 1;
u_char fc_to_ds : 1;
};
struct rts_frame {
struct frame_control rf_fc;
u_int16_t rf_duration;
u_char rf_ra[ETHER_ADDR_LEN];
u_char rf_ta[ETHER_ADDR_LEN];
u_char rf_fcs[ETHER_FCS_LEN];
};
struct cts_frame {
struct frame_control cf_fc;
u_int16_t cf_duration;
u_char cf_ra[ETHER_ADDR_LEN];
u_char cf_fcs[ETHER_FCS_LEN];
};
struct ack_frame {
struct frame_control af_fc;
u_int16_t af_duration;
u_char af_ra[ETHER_ADDR_LEN];
u_char af_fcs[ETHER_FCS_LEN];
};
struct beacon_frame {
struct frame_control bf_fc;
u_int16_t bf_duration;
u_char bf_ra[ETHER_ADDR_LEN];
u_char bf_ta[ETHER_ADDR_LEN];
u_char bf_3a[ETHER_ADDR_LEN];
u_int16_t bf_scontrol;
double bf_timestamp;
double bf_bcninterval;
u_int8_t bf_datarates[1];
u_char bf_fcs[ETHER_FCS_LEN];
};
struct assocreq_frame {
struct frame_control acrqf_fc;
u_int16_t acrqf_duration;
u_char acrqf_ra[ETHER_ADDR_LEN];
u_char acrqf_ta[ETHER_ADDR_LEN];
u_char acrqf_3a[ETHER_ADDR_LEN];
u_int16_t acrqf_scontrol;
u_char acrqf_fcs[ETHER_FCS_LEN];
};
struct assocrep_frame {
struct frame_control acrpf_fc;
u_int16_t acrpf_duration;
u_char acrpf_ra[ETHER_ADDR_LEN];
u_char acrpf_ta[ETHER_ADDR_LEN];
u_char acrpf_3a[ETHER_ADDR_LEN];
u_int16_t acrpf_scontrol;
u_int16_t acrpf_statuscode;
u_char acrpf_fcs[ETHER_FCS_LEN];
};
struct auth_frame {
struct frame_control authf_fc;
u_int16_t authf_duration;
u_char authf_ra[ETHER_ADDR_LEN];
u_char authf_ta[ETHER_ADDR_LEN];
u_char authf_3a[ETHER_ADDR_LEN];
u_int16_t authf_scontrol;
u_int16_t authf_algono;
u_int16_t authf_seqno;
u_int16_t authf_statuscode;
u_char authf_fcs[ETHER_FCS_LEN];
};
struct probereq_frame {
struct frame_control prrqf_fc;
u_int16_t prrqf_duration;
u_char prrqf_ra[ETHER_ADDR_LEN];
u_char prrqf_ta[ETHER_ADDR_LEN];
u_char prrqf_3a[ETHER_ADDR_LEN];
u_int16_t prrqf_scontrol;
u_char prrqf_fcs[ETHER_FCS_LEN];
};
struct proberep_frame {
struct frame_control prrpf_fc;
u_int16_t prrpf_duration;
u_char prrpf_ra[ETHER_ADDR_LEN];
u_char prrpf_ta[ETHER_ADDR_LEN];
u_char prrpf_3a[ETHER_ADDR_LEN];
u_int16_t prrpf_scontrol;
double prrpf_timestamp;
double prrpf_bcninterval;
u_int8_t prrpf_datarates[1];
u_char prrpf_fcs[ETHER_FCS_LEN];
};
// XXX This header does not have its header access function because it shares
// the same header space with hdr_mac.
struct hdr_mac802_11 {
struct frame_control dh_fc;
u_int16_t dh_duration;
u_char dh_ra[ETHER_ADDR_LEN];
u_char dh_ta[ETHER_ADDR_LEN];
u_char dh_3a[ETHER_ADDR_LEN];
u_char dh_4a[ETHER_ADDR_LEN];
u_int16_t dh_scontrol;
u_char dh_body[1]; // size of 1 for ANSI compatibility
};
struct client_table {
int client_id;
int auth_status;
int assoc_status;
};
struct ap_table {
int ap_id;
double ap_power;
};
struct priority_queue {
int frame_priority;
struct priority_queue *next;
};
/* ======================================================================
Definitions
====================================================================== */
/* Must account for propagation delays added by the channel model when
* calculating tx timeouts (as set in tcl/lan/ns-mac.tcl).
* -- Gavin Holland, March 2002
*/
#define DSSS_MaxPropagationDelay 0.000002 // 2us XXXX
class PHY_MIB {
public:
PHY_MIB(Mac802_11 *parent);
inline u_int32_t getCWMin() { return(CWMin); }
inline u_int32_t getCWMax() { return(CWMax); }
inline double getSlotTime() { return(SlotTime); }
inline double getBeaconInterval() { return(BeaconInterval); }
inline double getSIFS() { return(SIFSTime); }
inline double getPIFS() { return(SIFSTime + SlotTime); }
inline double getDIFS() { return(SIFSTime + 2 * SlotTime); }
inline double getEIFS() {
// see (802.11-1999, 9.2.10)
return(SIFSTime + getDIFS()
+ (8 * getACKlen())/PLCPDataRate);
}
inline u_int32_t getPreambleLength() { return(PreambleLength); }
inline double getPLCPDataRate() { return(PLCPDataRate); }
inline u_int32_t getPLCPhdrLen() {
return((PreambleLength + PLCPHeaderLength) >> 3);
}
inline u_int32_t getHdrLen11() {
return(getPLCPhdrLen() + offsetof(struct hdr_mac802_11, dh_body[0])
+ ETHER_FCS_LEN);
}
inline u_int32_t getRTSlen() {
return(getPLCPhdrLen() + sizeof(struct rts_frame));
}
inline u_int32_t getCTSlen() {
return(getPLCPhdrLen() + sizeof(struct cts_frame));
}
inline u_int32_t getACKlen() {
return(getPLCPhdrLen() + sizeof(struct ack_frame));
}
inline u_int32_t getBEACONlen() {
return(getPLCPhdrLen() + sizeof(struct beacon_frame));
}
inline u_int32_t getASSOCREQlen() {
return(getPLCPhdrLen() + sizeof(struct assocreq_frame));
}
inline u_int32_t getASSOCREPlen() {
return(getPLCPhdrLen() + sizeof(struct assocrep_frame));
}
inline u_int32_t getAUTHENTICATElen() {
return(getPLCPhdrLen() + sizeof(struct auth_frame));
}
inline u_int32_t getPROBEREQlen() {
return(getPLCPhdrLen() + sizeof(struct probereq_frame));
}
inline u_int32_t getPROBEREPlen() {
return(getPLCPhdrLen() + sizeof(struct proberep_frame));
}
private:
u_int32_t CWMin;
u_int32_t CWMax;
double SlotTime;
double SIFSTime;
double BeaconInterval;
u_int32_t PreambleLength;
u_int32_t PLCPHeaderLength;
double PLCPDataRate;
};
/*
* IEEE 802.11 Spec, section 11.4.4.2
* - default values for the MAC Attributes
*/
#define MAC_FragmentationThreshold 2346 // bytes
#define MAC_MaxTransmitMSDULifetime 512 // time units
#define MAC_MaxReceiveLifetime 512 // time units
class MAC_MIB {
public:
MAC_MIB(Mac802_11 *parent);
private:
u_int32_t RTSThreshold;
u_int32_t ShortRetryLimit;
u_int32_t LongRetryLimit;
u_int32_t ScanType;
double ProbeDelay;
double MaxChannelTime;
double MinChannelTime;
double ChannelTime;
public:
u_int32_t FailedCount;
u_int32_t RTSFailureCount;
u_int32_t ACKFailureCount;
public:
inline u_int32_t getRTSThreshold() { return(RTSThreshold);}
inline u_int32_t getShortRetryLimit() { return(ShortRetryLimit);}
inline u_int32_t getLongRetryLimit() { return(LongRetryLimit);}
inline u_int32_t getScanType() { return(ScanType);}
inline double getProbeDelay() { return(ProbeDelay);}
inline double getMaxChannelTime() { return(MaxChannelTime);}
inline double getMinChannelTime() { return(MinChannelTime);}
inline double getChannelTime() { return(ChannelTime);}
};
/* ======================================================================
The following destination class is used for duplicate detection.
====================================================================== */
class Host {
public:
LIST_ENTRY(Host) link;
u_int32_t index;
u_int32_t seqno;
};
/* ======================================================================
The actual 802.11 MAC class.
====================================================================== */
class Mac802_11 : public Mac {
friend class DeferTimer;
friend class BeaconTimer;
friend class ProbeTimer;
friend class BackoffTimer;
friend class IFTimer;
friend class NavTimer;
friend class RxTimer;
friend class TxTimer;
public:
Mac802_11();
void recv(Packet *p, Handler *h);
inline int hdr_dst(char* hdr, int dst = -2);
inline int hdr_src(char* hdr, int src = -2);
inline int hdr_type(char* hdr, u_int16_t type = 0);
inline int bss_id() { return bss_id_; }
// Added by Sushmita to support event tracing
void trace_event(char *, Packet *);
EventTrace *et_;
protected:
void backoffHandler(void);
void deferHandler(void);
void BeaconHandler(void);
void ProbeHandler(void);
void navHandler(void);
void recvHandler(void);
void sendHandler(void);
void txHandler(void);
private:
void update_client_table(int num, int auth_status, int assoc_status);
int find_client(int num);
void update_ap_table(int num, double power);
int strongest_ap();
int find_ap(int num, double power);
void deletelist();
void passive_scan();
void active_scan();
void checkAssocAuthStatus();
int command(int argc, const char*const* argv);
void add_priority_queue(int num);
void push_priority(int num);
void delete_lastnode();
void shift_priority_queue();
/* In support of bug fix described at
* http://www.dei.unipd.it/wdyn/?IDsezione=2435
*/
int bugFix_timer_;
int infra_mode_;
double BeaconTxtime_;
int associated;
int authenticated;
int handoff;
double Pr;
int ap_temp;
int ap_addr;
int tx_mgmt_;
int associating_node_;
int authenticating_node_;
int ScanType_;
int OnMinChannelTime;
int OnMaxChannelTime;
int Recv_Busy_;
int probe_delay;
/*
* Called by the timers.
*/
void recv_timer(void);
void send_timer(void);
int check_pktCTRL();
int check_pktRTS();
int check_pktTx();
int check_pktASSOCREQ();
int check_pktASSOCREP();
int check_pktBEACON();
int check_pktAUTHENTICATE();
int check_pktPROBEREQ();
int check_pktPROBEREP();
/*
* Packet Transmission Functions.
*/
void send(Packet *p, Handler *h);
void sendRTS(int dst);
void sendCTS(int dst, double duration);
void sendACK(int dst);
void sendDATA(Packet *p);
void sendBEACON(int src);
void sendASSOCREQ(int dst);
void sendASSOCREP(int dst);
void sendPROBEREQ(int dst);
void sendPROBEREP(int dst);
void sendAUTHENTICATE(int dst);
void RetransmitRTS();
void RetransmitDATA();
void RetransmitASSOCREP();
void RetransmitPROBEREP();
void RetransmitAUTHENTICATE();
/*
* Packet Reception Functions.
*/
void recvRTS(Packet *p);
void recvCTS(Packet *p);
void recvACK(Packet *p);
void recvDATA(Packet *p);
void recvBEACON(Packet *p);
void recvASSOCREQ(Packet *p);
void recvASSOCREP(Packet *p);
void recvPROBEREQ(Packet *p);
void recvPROBEREP(Packet *p);
void recvAUTHENTICATE(Packet *p);
void capture(Packet *p);
void collision(Packet *p);
void discard(Packet *p, const char* why);
void rx_resume(void);
void tx_resume(void);
inline int is_idle(void);
/*
* Debugging Functions.
*/
void trace_pkt(Packet *p);
void dump(char* fname);
inline int initialized() {
return (cache_ && logtarget_
&& Mac::initialized());
}
inline void mac_log(Packet *p) {
logtarget_->recv(p, (Handler*) 0);
}
double txtime(Packet *p);
double txtime(double psz, double drt);
double txtime(int bytes);
inline void transmit(Packet *p, double timeout);
inline void checkBackoffTimer(void);
inline void postBackoff(int pri);
inline void setRxState(MacState newState);
inline void setTxState(MacState newState);
inline void inc_cw() {
cw_ = (cw_ << 1) + 1;
if(cw_ > phymib_.getCWMax())
cw_ = phymib_.getCWMax();
}
inline void rst_cw() { cw_ = phymib_.getCWMin(); }
inline double sec(double t) { return(t *= 1.0e-6); }
inline u_int16_t usec(double t) {
u_int16_t us = (u_int16_t)floor((t *= 1e6) + 0.5);
return us;
}
inline void set_nav(u_int16_t us) {
double now = Scheduler::instance().clock();
double t = us * 1e-6;
if((now + t) > nav_) {
nav_ = now + t;
if(mhNav_.busy())
mhNav_.stop();
mhNav_.start(t);
}
}
protected:
PHY_MIB phymib_;
MAC_MIB macmib_;
/* the macaddr of my AP in BSS mode; for IBSS mode
* this is set to a reserved value IBSS_ID - the
* MAC_BROADCAST reserved value can be used for this
* purpose
*/
int bss_id_;
enum {IBSS_ID=MAC_BROADCAST};
enum {
PASSIVE = 0,
ACTIVE = 1
};
private:
double basicRate_;
double dataRate_;
struct client_table *client_list;
struct ap_table *ap_list;
struct priority_queue *queue_head;
/*
* Mac Timers
*/
IFTimer mhIF_; // interface timer
NavTimer mhNav_; // NAV timer
RxTimer mhRecv_; // incoming packets
TxTimer mhSend_; // outgoing packets
DeferTimer mhDefer_; // defer timer
BackoffTimer mhBackoff_; // backoff timer
BeaconTimer mhBeacon_; // Beacon Timer
ProbeTimer mhProbe_; //Probe timer,
/* ============================================================
Internal MAC State
============================================================ */
double nav_; // Network Allocation Vector
MacState rx_state_; // incoming state (MAC_RECV or MAC_IDLE)
MacState tx_state_; // outgoint state
int tx_active_; // transmitter is ACTIVE
Packet *eotPacket_; // copy for eot callback
Packet *pktRTS_; // outgoing RTS packet
Packet *pktCTRL_; // outgoing non-RTS packet
Packet *pktBEACON_; //outgoing Beacon Packet
Packet *pktASSOCREQ_; //Association request
Packet *pktASSOCREP_; // Association response
Packet *pktAUTHENTICATE_; //Authentication
Packet *pktPROBEREQ_; //Probe Request
Packet *pktPROBEREP_; //Probe Response
u_int32_t cw_; // Contention Window
u_int32_t ssrc_; // STA Short Retry Count
u_int32_t slrc_; // STA Long Retry Count
int min_frame_len_;
NsObject* logtarget_;
NsObject* EOTtarget_; // given a copy of packet at TX end
/* ============================================================
Duplicate Detection state
============================================================ */
u_int16_t sta_seqno_; // next seqno that I'll use
int cache_node_count_;
Host *cache_;
std::list<struct client_table> client_list1;
std::list<struct ap_table> ap_list1;
};
#endif /* __mac_80211_h__ */
|