#include <Ieee80211MgmtSTA.h>
Protected Types | |
typedef std::list< APInfo > | AccessPointList |
Protected Member Functions | |
virtual int | numInitStages () const |
virtual void | initialize (int) |
virtual void | handleTimer (cMessage *msg) |
virtual void | handleUpperMessage (cPacket *msg) |
virtual void | handleCommand (int msgkind, cPolymorphic *ctrl) |
virtual Ieee80211DataFrame * | encapsulate (cPacket *msg) |
virtual void | startAuthentication (APInfo *ap, simtime_t timeout) |
virtual void | startAssociation (APInfo *ap, simtime_t timeout) |
virtual APInfo * | lookupAP (const MACAddress &address) |
virtual void | clearAPList () |
virtual void | changeChannel (int channelNum) |
virtual void | storeAPInfo (const MACAddress &address, const Ieee80211BeaconFrameBody &body) |
virtual bool | scanNextChannel () |
virtual void | sendProbeRequest () |
virtual void | beaconLost () |
virtual void | sendScanConfirm () |
virtual void | sendAuthenticationConfirm (APInfo *ap, int resultCode) |
virtual void | sendAssociationConfirm (APInfo *ap, int resultCode) |
virtual void | disassociate () |
virtual void | sendConfirm (Ieee80211PrimConfirm *confirm, int resultCode) |
virtual void | sendManagementFrame (Ieee80211ManagementFrame *frame, const MACAddress &address) |
virtual void | receiveChangeNotification (int category, const cPolymorphic *details) |
virtual int | statusCodeToPrimResultCode (int statusCode) |
Processing of different frame types | |
virtual void | handleDataFrame (Ieee80211DataFrame *frame) |
virtual void | handleAuthenticationFrame (Ieee80211AuthenticationFrame *frame) |
virtual void | handleDeauthenticationFrame (Ieee80211DeauthenticationFrame *frame) |
virtual void | handleAssociationRequestFrame (Ieee80211AssociationRequestFrame *frame) |
virtual void | handleAssociationResponseFrame (Ieee80211AssociationResponseFrame *frame) |
virtual void | handleReassociationRequestFrame (Ieee80211ReassociationRequestFrame *frame) |
virtual void | handleReassociationResponseFrame (Ieee80211ReassociationResponseFrame *frame) |
virtual void | handleDisassociationFrame (Ieee80211DisassociationFrame *frame) |
virtual void | handleBeaconFrame (Ieee80211BeaconFrame *frame) |
virtual void | handleProbeRequestFrame (Ieee80211ProbeRequestFrame *frame) |
virtual void | handleProbeResponseFrame (Ieee80211ProbeResponseFrame *frame) |
Processing of different agent commands | |
virtual void | processScanCommand (Ieee80211Prim_ScanRequest *ctrl) |
virtual void | processAuthenticateCommand (Ieee80211Prim_AuthenticateRequest *ctrl) |
virtual void | processDeauthenticateCommand (Ieee80211Prim_DeauthenticateRequest *ctrl) |
virtual void | processAssociateCommand (Ieee80211Prim_AssociateRequest *ctrl) |
virtual void | processReassociateCommand (Ieee80211Prim_ReassociateRequest *ctrl) |
virtual void | processDisassociateCommand (Ieee80211Prim_DisassociateRequest *ctrl) |
Protected Attributes | |
NotificationBoard * | nb |
int | numChannels |
bool | isScanning |
ScanningInfo | scanning |
AccessPointList | apList |
bool | isAssociated |
cMessage * | assocTimeoutMsg |
AssociatedAPInfo | assocAP |
Classes | |
struct | APInfo |
struct | AssociatedAPInfo |
struct | ScanningInfo |
typedef std::list<APInfo> Ieee80211MgmtSTA::AccessPointList [protected] |
virtual int Ieee80211MgmtSTA::numInitStages | ( | ) | const [inline, protected, virtual] |
void Ieee80211MgmtSTA::initialize | ( | int | stage | ) | [protected, virtual] |
Reimplemented from Ieee80211MgmtBase.
00089 { 00090 Ieee80211MgmtBase::initialize(stage); 00091 if (stage==0) 00092 { 00093 isScanning = false; 00094 isAssociated = false; 00095 assocTimeoutMsg = NULL; 00096 00097 nb = NotificationBoardAccess().get(); 00098 00099 // determine numChannels (needed when we're told to scan "all" channels) 00100 //XXX find a better way than directly accessing channelControl 00101 cModule *cc = ChannelControl::get(); 00102 numChannels = cc->par("numChannels"); 00103 00104 WATCH(isScanning); 00105 WATCH(isAssociated); 00106 00107 WATCH(scanning); 00108 WATCH(assocAP); 00109 WATCH_LIST(apList); 00110 } 00111 }
void Ieee80211MgmtSTA::handleTimer | ( | cMessage * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
00114 { 00115 if (msg->getKind()==MK_AUTH_TIMEOUT) 00116 { 00117 // authentication timed out 00118 APInfo *ap = (APInfo *)msg->getContextPointer(); 00119 EV << "Authentication timed out, AP address = " << ap->address << "\n"; 00120 00121 // send back failure report to agent 00122 sendAuthenticationConfirm(ap, PRC_TIMEOUT); 00123 } 00124 else if (msg->getKind()==MK_ASSOC_TIMEOUT) 00125 { 00126 // association timed out 00127 APInfo *ap = (APInfo *)msg->getContextPointer(); 00128 EV << "Association timed out, AP address = " << ap->address << "\n"; 00129 00130 // send back failure report to agent 00131 sendAssociationConfirm(ap, PRC_TIMEOUT); 00132 } 00133 else if (msg->getKind()==MK_SCAN_MAXCHANNELTIME) 00134 { 00135 // go to next channel during scanning 00136 bool done = scanNextChannel(); 00137 if (done) 00138 sendScanConfirm(); // send back response to agents' "scan" command 00139 delete msg; 00140 } 00141 else if (msg->getKind()==MK_SCAN_SENDPROBE) 00142 { 00143 // Active Scan: send a probe request, then wait for minChannelTime (11.1.3.2.2) 00144 delete msg; 00145 sendProbeRequest(); 00146 cMessage *timerMsg = new cMessage("minChannelTime", MK_SCAN_MINCHANNELTIME); 00147 scheduleAt(simTime()+scanning.minChannelTime, timerMsg); //XXX actually, we should start waiting after ProbeReq actually got transmitted 00148 } 00149 else if (msg->getKind()==MK_SCAN_MINCHANNELTIME) 00150 { 00151 // Active Scan: after minChannelTime, possibly listen for the remaining time until maxChannelTime 00152 delete msg; 00153 if (scanning.busyChannelDetected) 00154 { 00155 EV << "Busy channel detected during minChannelTime, continuing listening until maxChannelTime elapses\n"; 00156 cMessage *timerMsg = new cMessage("maxChannelTime", MK_SCAN_MAXCHANNELTIME); 00157 scheduleAt(simTime()+scanning.maxChannelTime - scanning.minChannelTime, timerMsg); 00158 } 00159 else 00160 { 00161 EV << "Channel was empty during minChannelTime, going to next channel\n"; 00162 bool done = scanNextChannel(); 00163 if (done) 00164 sendScanConfirm(); // send back response to agents' "scan" command 00165 } 00166 } 00167 else if (msg->getKind()==MK_BEACON_TIMEOUT) 00168 { 00169 // missed a few consecutive beacons 00170 beaconLost(); 00171 } 00172 else 00173 { 00174 error("internal error: unrecognized timer '%s'", msg->getName()); 00175 } 00176 }
void Ieee80211MgmtSTA::handleUpperMessage | ( | cPacket * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
00179 { 00180 Ieee80211DataFrame *frame = encapsulate(msg); 00181 sendOrEnqueue(frame); 00182 }
void Ieee80211MgmtSTA::handleCommand | ( | int | msgkind, | |
cPolymorphic * | ctrl | |||
) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
00185 { 00186 if (dynamic_cast<Ieee80211Prim_ScanRequest *>(ctrl)) 00187 processScanCommand((Ieee80211Prim_ScanRequest *)ctrl); 00188 else if (dynamic_cast<Ieee80211Prim_AuthenticateRequest *>(ctrl)) 00189 processAuthenticateCommand((Ieee80211Prim_AuthenticateRequest *)ctrl); 00190 else if (dynamic_cast<Ieee80211Prim_DeauthenticateRequest *>(ctrl)) 00191 processDeauthenticateCommand((Ieee80211Prim_DeauthenticateRequest *)ctrl); 00192 else if (dynamic_cast<Ieee80211Prim_AssociateRequest *>(ctrl)) 00193 processAssociateCommand((Ieee80211Prim_AssociateRequest *)ctrl); 00194 else if (dynamic_cast<Ieee80211Prim_ReassociateRequest *>(ctrl)) 00195 processReassociateCommand((Ieee80211Prim_ReassociateRequest *)ctrl); 00196 else if (dynamic_cast<Ieee80211Prim_DisassociateRequest *>(ctrl)) 00197 processDisassociateCommand((Ieee80211Prim_DisassociateRequest *)ctrl); 00198 else if (ctrl) 00199 error("handleCommand(): unrecognized control info class `%s'", ctrl->getClassName()); 00200 else 00201 error("handleCommand(): control info is NULL"); 00202 delete ctrl; 00203 }
Ieee80211DataFrame * Ieee80211MgmtSTA::encapsulate | ( | cPacket * | msg | ) | [protected, virtual] |
Utility function for handleUpperMessage()
Referenced by handleUpperMessage().
00206 { 00207 Ieee80211DataFrame *frame = new Ieee80211DataFrame(msg->getName()); 00208 00209 // frame goes to the AP 00210 frame->setToDS(true); 00211 00212 // receiver is the AP 00213 frame->setReceiverAddress(assocAP.address); 00214 00215 // destination address is in address3 00216 Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(msg->removeControlInfo()); 00217 frame->setAddress3(ctrl->getDest()); 00218 delete ctrl; 00219 00220 frame->encapsulate(msg); 00221 return frame; 00222 }
void Ieee80211MgmtSTA::startAuthentication | ( | APInfo * | ap, | |
simtime_t | timeout | |||
) | [protected, virtual] |
Utility function: sends authentication request
Referenced by processAuthenticateCommand().
00269 { 00270 if (ap->authTimeoutMsg) 00271 error("startAuthentication: authentication currently in progress with AP address=", ap->address.str().c_str()); 00272 if (ap->isAuthenticated) 00273 error("startAuthentication: already authenticated with AP address=", ap->address.str().c_str()); 00274 00275 changeChannel(ap->channel); 00276 00277 EV << "Sending initial Authentication frame with seqNum=1\n"; 00278 00279 // create and send first authentication frame 00280 Ieee80211AuthenticationFrame *frame = new Ieee80211AuthenticationFrame("Auth"); 00281 frame->getBody().setSequenceNumber(1); 00282 //XXX frame length could be increased to account for challenge text length etc. 00283 sendManagementFrame(frame, ap->address); 00284 00285 ap->authSeqExpected = 2; 00286 00287 // schedule timeout 00288 ASSERT(ap->authTimeoutMsg==NULL); 00289 ap->authTimeoutMsg = new cMessage("authTimeout", MK_AUTH_TIMEOUT); 00290 ap->authTimeoutMsg->setContextPointer(ap); 00291 scheduleAt(simTime()+timeout, ap->authTimeoutMsg); 00292 }
void Ieee80211MgmtSTA::startAssociation | ( | APInfo * | ap, | |
simtime_t | timeout | |||
) | [protected, virtual] |
Utility function: sends association request
Referenced by processAssociateCommand().
00295 { 00296 if (isAssociated || assocTimeoutMsg) 00297 error("startAssociation: already associated or association currently in progress"); 00298 if (!ap->isAuthenticated) 00299 error("startAssociation: not yet authenticated with AP address=", ap->address.str().c_str()); 00300 00301 // switch to that channel 00302 changeChannel(ap->channel); 00303 00304 // create and send association request 00305 Ieee80211AssociationRequestFrame *frame = new Ieee80211AssociationRequestFrame("Assoc"); 00306 00307 //XXX set the following too? 00308 // string SSID 00309 // Ieee80211SupportedRatesElement supportedRates; 00310 00311 sendManagementFrame(frame, ap->address); 00312 00313 // schedule timeout 00314 ASSERT(assocTimeoutMsg==NULL); 00315 assocTimeoutMsg = new cMessage("assocTimeout", MK_ASSOC_TIMEOUT); 00316 assocTimeoutMsg->setContextPointer(ap); 00317 scheduleAt(simTime()+timeout, assocTimeoutMsg); 00318 }
Ieee80211MgmtSTA::APInfo * Ieee80211MgmtSTA::lookupAP | ( | const MACAddress & | address | ) | [protected, virtual] |
Utility function: looks up AP in our AP list. Returns NULL if not found.
Referenced by handleAssociationResponseFrame(), handleAuthenticationFrame(), handleDeauthenticationFrame(), processAssociateCommand(), processAuthenticateCommand(), processDeauthenticateCommand(), and storeAPInfo().
00225 { 00226 for (AccessPointList::iterator it=apList.begin(); it!=apList.end(); ++it) 00227 if (it->address == address) 00228 return &(*it); 00229 return NULL; 00230 }
void Ieee80211MgmtSTA::clearAPList | ( | ) | [protected, virtual] |
Utility function: clear the AP list, and cancel any pending authentications.
Referenced by processScanCommand().
00233 { 00234 for (AccessPointList::iterator it=apList.begin(); it!=apList.end(); ++it) 00235 if (it->authTimeoutMsg) 00236 delete cancelEvent(it->authTimeoutMsg); 00237 apList.clear(); 00238 }
void Ieee80211MgmtSTA::changeChannel | ( | int | channelNum | ) | [protected, virtual] |
Utility function: switches to the given radio channel.
Referenced by scanNextChannel(), startAssociation(), and startAuthentication().
00241 { 00242 EV << "Tuning to channel #" << channelNum << "\n"; 00243 00244 // sending PHY_C_CONFIGURERADIO command to MAC 00245 PhyControlInfo *phyCtrl = new PhyControlInfo(); 00246 phyCtrl->setChannelNumber(channelNum); 00247 cMessage *msg = new cMessage("changeChannel", PHY_C_CONFIGURERADIO); 00248 msg->setControlInfo(phyCtrl); 00249 send(msg, "macOut"); 00250 }
void Ieee80211MgmtSTA::storeAPInfo | ( | const MACAddress & | address, | |
const Ieee80211BeaconFrameBody & | body | |||
) | [protected, virtual] |
Stores AP info received in a beacon or probe response
Referenced by handleBeaconFrame(), and handleProbeResponseFrame().
00793 { 00794 APInfo *ap = lookupAP(address); 00795 if (ap) 00796 { 00797 EV << "AP address=" << address << ", SSID=" << body.getSSID() << " already in our AP list, refreshing the info\n"; 00798 } 00799 else 00800 { 00801 EV << "Inserting AP address=" << address << ", SSID=" << body.getSSID() << " into our AP list\n"; 00802 apList.push_back(APInfo()); 00803 ap = &apList.back(); 00804 } 00805 00806 ap->channel = body.getChannelNumber(); 00807 ap->address = address; 00808 ap->ssid = body.getSSID(); 00809 ap->supportedRates = body.getSupportedRates(); 00810 ap->beaconInterval = body.getBeaconInterval(); 00811 00812 //XXX where to get this from? 00813 //ap->rxPower = ... 00814 }
bool Ieee80211MgmtSTA::scanNextChannel | ( | ) | [protected, virtual] |
Switches to the next channel to scan; returns true if done (there wasn't any more channel to scan).
Referenced by handleTimer(), and processScanCommand().
00384 { 00385 // if we're already at the last channel, we're through 00386 if (scanning.currentChannelIndex==(int)scanning.channelList.size()-1) 00387 { 00388 EV << "Finished scanning last channel\n"; 00389 if (scanning.activeScan) 00390 nb->unsubscribe(this, NF_RADIOSTATE_CHANGED); 00391 isScanning = false; 00392 return true; // we're done 00393 } 00394 00395 // tune to next channel 00396 int newChannel = scanning.channelList[++scanning.currentChannelIndex]; 00397 changeChannel(newChannel); 00398 scanning.busyChannelDetected = false; 00399 00400 if (scanning.activeScan) 00401 { 00402 // Active Scan: first wait probeDelay, then send a probe. Listening 00403 // for minChannelTime or maxChannelTime takes place after that. (11.1.3.2) 00404 scheduleAt(simTime()+scanning.probeDelay, new cMessage("sendProbe", MK_SCAN_SENDPROBE)); 00405 } 00406 else 00407 { 00408 // Passive Scan: spend maxChannelTime on the channel (11.1.3.1) 00409 cMessage *timerMsg = new cMessage("maxChannelTime", MK_SCAN_MAXCHANNELTIME); 00410 scheduleAt(simTime()+scanning.maxChannelTime, timerMsg); 00411 } 00412 00413 return false; 00414 }
void Ieee80211MgmtSTA::sendProbeRequest | ( | ) | [protected, virtual] |
Broadcasts a Probe Request
Referenced by handleTimer().
00417 { 00418 EV << "Sending Probe Request, BSSID=" << scanning.bssid << ", SSID=\"" << scanning.ssid << "\"\n"; 00419 Ieee80211ProbeRequestFrame *frame = new Ieee80211ProbeRequestFrame("ProbeReq"); 00420 frame->getBody().setSSID(scanning.ssid.c_str()); 00421 sendManagementFrame(frame, scanning.bssid); 00422 }
void Ieee80211MgmtSTA::beaconLost | ( | ) | [protected, virtual] |
Missed a few consecutive beacons
Referenced by handleTimer().
00253 { 00254 EV << "Missed a few consecutive beacons -- AP is considered lost\n"; 00255 nb->fireChangeNotification(NF_L2_BEACON_LOST, NULL); //XXX use InterfaceEntry as detail, etc... 00256 }
void Ieee80211MgmtSTA::sendScanConfirm | ( | ) | [protected, virtual] |
Sends back result of scanning to the agent
Referenced by handleTimer().
00425 { 00426 EV << "Scanning complete, found " << apList.size() << " APs, sending confirmation to agent\n"; 00427 00428 // copy apList contents into a ScanConfirm primitive and send it back 00429 int n = apList.size(); 00430 Ieee80211Prim_ScanConfirm *confirm = new Ieee80211Prim_ScanConfirm(); 00431 confirm->setBssListArraySize(n); 00432 AccessPointList::iterator it = apList.begin(); 00433 //XXX filter for req'd bssid and ssid 00434 for (int i=0; i<n; i++, it++) 00435 { 00436 APInfo *ap = &(*it); 00437 Ieee80211Prim_BSSDescription& bss = confirm->getBssList(i); 00438 bss.setChannelNumber(ap->channel); 00439 bss.setBSSID(ap->address); 00440 bss.setSSID(ap->ssid.c_str()); 00441 bss.setSupportedRates(ap->supportedRates); 00442 bss.setBeaconInterval(ap->beaconInterval); 00443 bss.setRxPower(ap->rxPower); 00444 } 00445 sendConfirm(confirm, PRC_SUCCESS); 00446 }
void Ieee80211MgmtSTA::sendAuthenticationConfirm | ( | APInfo * | ap, | |
int | resultCode | |||
) | [protected, virtual] |
Sends back result of authentication to the agent
Referenced by handleAuthenticationFrame(), and handleTimer().
00531 { 00532 Ieee80211Prim_AuthenticateConfirm *confirm = new Ieee80211Prim_AuthenticateConfirm(); 00533 confirm->setAddress(ap->address); 00534 sendConfirm(confirm, resultCode); 00535 }
void Ieee80211MgmtSTA::sendAssociationConfirm | ( | APInfo * | ap, | |
int | resultCode | |||
) | [protected, virtual] |
Sends back result of association to the agent
Referenced by handleAssociationResponseFrame(), and handleTimer().
00538 { 00539 sendConfirm(new Ieee80211Prim_AssociateConfirm(), resultCode); 00540 }
void Ieee80211MgmtSTA::disassociate | ( | ) | [protected, virtual] |
Utility function: Cancel the existing association
Referenced by processDeauthenticateCommand(), processDisassociateCommand(), and processScanCommand().
00521 { 00522 EV << "Disassociating from AP address=" << assocAP.address << "\n"; 00523 ASSERT(isAssociated); 00524 isAssociated = false; 00525 delete cancelEvent(assocAP.beaconTimeoutMsg); 00526 assocAP.beaconTimeoutMsg = NULL; 00527 assocAP = AssociatedAPInfo(); // clear it 00528 }
void Ieee80211MgmtSTA::sendConfirm | ( | Ieee80211PrimConfirm * | confirm, | |
int | resultCode | |||
) | [protected, virtual] |
Utility function: sends a confirmation to the agent
Referenced by sendAssociationConfirm(), sendAuthenticationConfirm(), and sendScanConfirm().
00543 { 00544 confirm->setResultCode(resultCode); 00545 cMessage *msg = new cMessage(confirm->getClassName()); 00546 msg->setControlInfo(confirm); 00547 send(msg, "agentOut"); 00548 }
void Ieee80211MgmtSTA::sendManagementFrame | ( | Ieee80211ManagementFrame * | frame, | |
const MACAddress & | address | |||
) | [protected, virtual] |
Utility function: sends a management frame
Referenced by handleAuthenticationFrame(), processDeauthenticateCommand(), processDisassociateCommand(), sendProbeRequest(), startAssociation(), and startAuthentication().
00259 { 00260 // frame goes to the specified AP 00261 frame->setToDS(true); 00262 frame->setReceiverAddress(address); 00263 //XXX set sequenceNumber? 00264 00265 sendOrEnqueue(frame); 00266 }
void Ieee80211MgmtSTA::receiveChangeNotification | ( | int | category, | |
const cPolymorphic * | details | |||
) | [protected, virtual] |
Called by the NotificationBoard whenever a change occurs we're interested in
Implements INotifiable.
00321 { 00322 Enter_Method_Silent(); 00323 printNotificationBanner(category, details); 00324 00325 // Note that we are only subscribed during scanning! 00326 if (category==NF_RADIOSTATE_CHANGED) 00327 { 00328 RadioState::State radioState = check_and_cast<RadioState *>(details)->getState(); 00329 if (radioState==RadioState::RECV) 00330 { 00331 EV << "busy radio channel detected during scanning\n"; 00332 scanning.busyChannelDetected = true; 00333 } 00334 } 00335 }
int Ieee80211MgmtSTA::statusCodeToPrimResultCode | ( | int | statusCode | ) | [protected, virtual] |
Utility function: converts Ieee80211StatusCode (->frame) to Ieee80211PrimResultCode (->primitive)
Referenced by handleAssociationResponseFrame(), and handleAuthenticationFrame().
void Ieee80211MgmtSTA::handleDataFrame | ( | Ieee80211DataFrame * | frame | ) | [protected, virtual] |
void Ieee80211MgmtSTA::handleAuthenticationFrame | ( | Ieee80211AuthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00561 { 00562 MACAddress address = frame->getTransmitterAddress(); 00563 int frameAuthSeq = frame->getBody().getSequenceNumber(); 00564 EV << "Received Authentication frame from address=" << address << ", seqNum=" << frameAuthSeq << "\n"; 00565 00566 APInfo *ap = lookupAP(address); 00567 if (!ap) 00568 { 00569 EV << "AP not known, discarding authentication frame\n"; 00570 delete frame; 00571 return; 00572 } 00573 00574 // what if already authenticated with AP 00575 if (ap->isAuthenticated) 00576 { 00577 EV << "AP already authenticated, ignoring frame\n"; 00578 delete frame; 00579 return; 00580 } 00581 00582 // is authentication is in progress with this AP? 00583 if (!ap->authTimeoutMsg) 00584 { 00585 EV << "No authentication in progress with AP, ignoring frame\n"; 00586 delete frame; 00587 return; 00588 } 00589 00590 // check authentication sequence number is OK 00591 if (frameAuthSeq != ap->authSeqExpected) 00592 { 00593 // wrong sequence number: send error and return 00594 EV << "Wrong sequence number, " << ap->authSeqExpected << " expected\n"; 00595 Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame("Auth-ERROR"); 00596 resp->getBody().setStatusCode(SC_AUTH_OUT_OF_SEQ); 00597 sendManagementFrame(resp, frame->getTransmitterAddress()); 00598 delete frame; 00599 00600 // cancel timeout, send error to agent 00601 delete cancelEvent(ap->authTimeoutMsg); 00602 ap->authTimeoutMsg = NULL; 00603 sendAuthenticationConfirm(ap, PRC_REFUSED); //XXX or what resultCode? 00604 return; 00605 } 00606 00607 // check if more exchanges are needed for auth to be complete 00608 int statusCode = frame->getBody().getStatusCode(); 00609 00610 if (statusCode==SC_SUCCESSFUL && !frame->getBody().getIsLast()) 00611 { 00612 EV << "More steps required, sending another Authentication frame\n"; 00613 00614 // more steps required, send another Authentication frame 00615 Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame("Auth"); 00616 resp->getBody().setSequenceNumber(frameAuthSeq+1); 00617 resp->getBody().setStatusCode(SC_SUCCESSFUL); 00618 // XXX frame length could be increased to account for challenge text length etc. 00619 sendManagementFrame(resp, address); 00620 ap->authSeqExpected += 2; 00621 } 00622 else 00623 { 00624 if (statusCode==SC_SUCCESSFUL) 00625 EV << "Authentication successful\n"; 00626 else 00627 EV << "Authentication failed\n"; 00628 00629 // authentication completed 00630 ap->isAuthenticated = (statusCode==SC_SUCCESSFUL); 00631 delete cancelEvent(ap->authTimeoutMsg); 00632 ap->authTimeoutMsg = NULL; 00633 sendAuthenticationConfirm(ap, statusCodeToPrimResultCode(statusCode)); 00634 } 00635 00636 delete frame; 00637 }
void Ieee80211MgmtSTA::handleDeauthenticationFrame | ( | Ieee80211DeauthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00640 { 00641 EV << "Received Deauthentication frame\n"; 00642 const MACAddress& address = frame->getAddress3(); // source address 00643 APInfo *ap = lookupAP(address); 00644 if (!ap || !ap->isAuthenticated) 00645 { 00646 EV << "Unknown AP, or not authenticated with that AP -- ignoring frame\n"; 00647 delete frame; 00648 return; 00649 } 00650 if (ap->authTimeoutMsg) 00651 { 00652 delete cancelEvent(ap->authTimeoutMsg); 00653 ap->authTimeoutMsg = NULL; 00654 EV << "Cancelling pending authentication\n"; 00655 delete frame; 00656 return; 00657 } 00658 00659 EV << "Setting isAuthenticated flag for that AP to false\n"; 00660 ap->isAuthenticated = false; 00661 }
void Ieee80211MgmtSTA::handleAssociationRequestFrame | ( | Ieee80211AssociationRequestFrame * | frame | ) | [protected, virtual] |
void Ieee80211MgmtSTA::handleAssociationResponseFrame | ( | Ieee80211AssociationResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00669 { 00670 EV << "Received Association Response frame\n"; 00671 00672 if (!assocTimeoutMsg) 00673 { 00674 EV << "No association in progress, ignoring frame\n"; 00675 delete frame; 00676 return; 00677 } 00678 00679 // extract frame contents 00680 MACAddress address = frame->getTransmitterAddress(); 00681 int statusCode = frame->getBody().getStatusCode(); 00682 //XXX short aid; 00683 //XXX Ieee80211SupportedRatesElement supportedRates; 00684 delete frame; 00685 00686 // look up AP data structure 00687 APInfo *ap = lookupAP(address); 00688 if (!ap) 00689 error("handleAssociationResponseFrame: AP not known: address=%s", address.str().c_str()); 00690 00691 if (isAssociated) 00692 { 00693 EV << "Breaking existing association with AP address=" << assocAP.address << "\n"; 00694 isAssociated = false; 00695 delete cancelEvent(assocAP.beaconTimeoutMsg); 00696 assocAP.beaconTimeoutMsg = NULL; 00697 assocAP = AssociatedAPInfo(); 00698 } 00699 00700 delete cancelEvent(assocTimeoutMsg); 00701 assocTimeoutMsg = NULL; 00702 00703 if (statusCode!=SC_SUCCESSFUL) 00704 { 00705 EV << "Association failed with AP address=" << ap->address << "\n"; 00706 } 00707 else 00708 { 00709 EV << "Association successful, AP address=" << ap->address << "\n"; 00710 00711 // change our state to "associated" 00712 isAssociated = true; 00713 (APInfo&)assocAP = (*ap); 00714 00715 nb->fireChangeNotification(NF_L2_ASSOCIATED, NULL); //XXX detail: InterfaceEntry? 00716 00717 assocAP.beaconTimeoutMsg = new cMessage("beaconTimeout", MK_BEACON_TIMEOUT); 00718 scheduleAt(simTime()+MAX_BEACONS_MISSED*assocAP.beaconInterval, assocAP.beaconTimeoutMsg); 00719 } 00720 00721 // report back to agent 00722 sendAssociationConfirm(ap, statusCodeToPrimResultCode(statusCode)); 00723 }
void Ieee80211MgmtSTA::handleReassociationRequestFrame | ( | Ieee80211ReassociationRequestFrame * | frame | ) | [protected, virtual] |
void Ieee80211MgmtSTA::handleReassociationResponseFrame | ( | Ieee80211ReassociationResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00731 { 00732 EV << "Received Reassociation Response frame\n"; 00733 //TBD handle with the same code as Association Response? 00734 }
void Ieee80211MgmtSTA::handleDisassociationFrame | ( | Ieee80211DisassociationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00737 { 00738 EV << "Received Disassociation frame\n"; 00739 const MACAddress& address = frame->getAddress3(); // source address 00740 00741 if (assocTimeoutMsg) 00742 { 00743 // pending association 00744 delete cancelEvent(assocTimeoutMsg); 00745 assocTimeoutMsg = NULL; 00746 } 00747 if (!isAssociated || address!=assocAP.address) 00748 { 00749 EV << "Not associated with that AP -- ignoring frame\n"; 00750 delete frame; 00751 return; 00752 } 00753 00754 EV << "Setting isAssociated flag to false\n"; 00755 isAssociated = false; 00756 delete cancelEvent(assocAP.beaconTimeoutMsg); 00757 assocAP.beaconTimeoutMsg = NULL; 00758 }
void Ieee80211MgmtSTA::handleBeaconFrame | ( | Ieee80211BeaconFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00761 { 00762 EV << "Received Beacon frame\n"; 00763 storeAPInfo(frame->getTransmitterAddress(), frame->getBody()); 00764 00765 // if it is out associate AP, restart beacon timeout 00766 if (isAssociated && frame->getTransmitterAddress()==assocAP.address) 00767 { 00768 EV << "Beacon is from associated AP, restarting beacon timeout timer\n"; 00769 ASSERT(assocAP.beaconTimeoutMsg!=NULL); 00770 cancelEvent(assocAP.beaconTimeoutMsg); 00771 scheduleAt(simTime()+MAX_BEACONS_MISSED*assocAP.beaconInterval, assocAP.beaconTimeoutMsg); 00772 00773 //APInfo *ap = lookupAP(frame->getTransmitterAddress()); 00774 //ASSERT(ap!=NULL); 00775 } 00776 00777 delete frame; 00778 }
void Ieee80211MgmtSTA::handleProbeRequestFrame | ( | Ieee80211ProbeRequestFrame * | frame | ) | [protected, virtual] |
void Ieee80211MgmtSTA::handleProbeResponseFrame | ( | Ieee80211ProbeResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
00786 { 00787 EV << "Received Probe Response frame\n"; 00788 storeAPInfo(frame->getTransmitterAddress(), frame->getBody()); 00789 delete frame; 00790 }
void Ieee80211MgmtSTA::processScanCommand | ( | Ieee80211Prim_ScanRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
00338 { 00339 EV << "Received Scan Request from agent, clearing AP list and starting scanning...\n"; 00340 00341 if (isScanning) 00342 error("processScanCommand: scanning already in progress"); 00343 if (isAssociated) 00344 { 00345 disassociate(); 00346 } 00347 else if (assocTimeoutMsg) 00348 { 00349 EV << "Cancelling ongoing association process\n"; 00350 delete cancelEvent(assocTimeoutMsg); 00351 assocTimeoutMsg = NULL; 00352 } 00353 00354 // clear existing AP list (and cancel any pending authentications) -- we want to start with a clean page 00355 clearAPList(); 00356 00357 // fill in scanning state 00358 ASSERT(ctrl->getBSSType()==BSSTYPE_INFRASTRUCTURE); 00359 scanning.bssid = ctrl->getBSSID().isUnspecified() ? MACAddress::BROADCAST_ADDRESS : ctrl->getBSSID(); 00360 scanning.ssid = ctrl->getSSID(); 00361 scanning.activeScan = ctrl->getActiveScan(); 00362 scanning.probeDelay = ctrl->getProbeDelay(); 00363 scanning.channelList.clear(); 00364 scanning.minChannelTime = ctrl->getMinChannelTime(); 00365 scanning.maxChannelTime = ctrl->getMaxChannelTime(); 00366 ASSERT(scanning.minChannelTime <= scanning.maxChannelTime); 00367 00368 // channel list to scan (default: all channels) 00369 for (int i=0; i<(int)ctrl->getChannelListArraySize(); i++) 00370 scanning.channelList.push_back(ctrl->getChannelList(i)); 00371 if (scanning.channelList.empty()) 00372 for (int i=0; i<numChannels; i++) 00373 scanning.channelList.push_back(i); 00374 00375 // start scanning 00376 if (scanning.activeScan) 00377 nb->subscribe(this, NF_RADIOSTATE_CHANGED); 00378 scanning.currentChannelIndex = -1; // so we'll start with index==0 00379 isScanning = true; 00380 scanNextChannel(); 00381 }
void Ieee80211MgmtSTA::processAuthenticateCommand | ( | Ieee80211Prim_AuthenticateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
00449 { 00450 const MACAddress& address = ctrl->getAddress(); 00451 APInfo *ap = lookupAP(address); 00452 if (!ap) 00453 error("processAuthenticateCommand: AP not known: address = %s", address.str().c_str()); 00454 startAuthentication(ap, ctrl->getTimeout()); 00455 }
void Ieee80211MgmtSTA::processDeauthenticateCommand | ( | Ieee80211Prim_DeauthenticateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
00458 { 00459 const MACAddress& address = ctrl->getAddress(); 00460 APInfo *ap = lookupAP(address); 00461 if (!ap) 00462 error("processDeauthenticateCommand: AP not known: address = %s", address.str().c_str()); 00463 00464 if (isAssociated && assocAP.address==address) 00465 disassociate(); 00466 00467 if (ap->isAuthenticated) 00468 ap->isAuthenticated = false; 00469 00470 // cancel possible pending authentication timer 00471 if (ap->authTimeoutMsg) 00472 { 00473 delete cancelEvent(ap->authTimeoutMsg); 00474 ap->authTimeoutMsg = NULL; 00475 } 00476 00477 // create and send deauthentication request 00478 Ieee80211DeauthenticationFrame *frame = new Ieee80211DeauthenticationFrame("Deauth"); 00479 frame->getBody().setReasonCode(ctrl->getReasonCode()); 00480 sendManagementFrame(frame, address); 00481 }
void Ieee80211MgmtSTA::processAssociateCommand | ( | Ieee80211Prim_AssociateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand(), and processReassociateCommand().
00484 { 00485 const MACAddress& address = ctrl->getAddress(); 00486 APInfo *ap = lookupAP(address); 00487 if (!ap) 00488 error("processAssociateCommand: AP not known: address = %s", address.str().c_str()); 00489 startAssociation(ap, ctrl->getTimeout()); 00490 }
void Ieee80211MgmtSTA::processReassociateCommand | ( | Ieee80211Prim_ReassociateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
00493 { 00494 // treat the same way as association 00495 //XXX refine 00496 processAssociateCommand(ctrl); 00497 }
void Ieee80211MgmtSTA::processDisassociateCommand | ( | Ieee80211Prim_DisassociateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
00500 { 00501 const MACAddress& address = ctrl->getAddress(); 00502 00503 if (isAssociated && address==assocAP.address) 00504 { 00505 disassociate(); 00506 } 00507 else if (assocTimeoutMsg) 00508 { 00509 // pending association 00510 delete cancelEvent(assocTimeoutMsg); 00511 assocTimeoutMsg = NULL; 00512 } 00513 00514 // create and send disassociation request 00515 Ieee80211DisassociationFrame *frame = new Ieee80211DisassociationFrame("Disass"); 00516 frame->getBody().setReasonCode(ctrl->getReasonCode()); 00517 sendManagementFrame(frame, address); 00518 }
NotificationBoard* Ieee80211MgmtSTA::nb [protected] |
Referenced by beaconLost(), handleAssociationResponseFrame(), initialize(), processScanCommand(), and scanNextChannel().
int Ieee80211MgmtSTA::numChannels [protected] |
Referenced by initialize(), and processScanCommand().
bool Ieee80211MgmtSTA::isScanning [protected] |
Referenced by initialize(), processScanCommand(), and scanNextChannel().
ScanningInfo Ieee80211MgmtSTA::scanning [protected] |
Referenced by handleTimer(), initialize(), processScanCommand(), receiveChangeNotification(), scanNextChannel(), and sendProbeRequest().
AccessPointList Ieee80211MgmtSTA::apList [protected] |
Referenced by clearAPList(), initialize(), lookupAP(), sendScanConfirm(), and storeAPInfo().
bool Ieee80211MgmtSTA::isAssociated [protected] |
cMessage* Ieee80211MgmtSTA::assocTimeoutMsg [protected] |
AssociatedAPInfo Ieee80211MgmtSTA::assocAP [protected] |