INET Framework for OMNeT++/OMNEST
|
#include <Ieee80211MgmtSTA.h>
Classes | |
struct | APInfo |
struct | AssociatedAPInfo |
struct | ScanningInfo |
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 |
Used in 802.11 infrastructure mode: handles management frames for a station (STA). See corresponding NED file for a detailed description.
typedef std::list<APInfo> Ieee80211MgmtSTA::AccessPointList [protected] |
void Ieee80211MgmtSTA::beaconLost | ( | ) | [protected, virtual] |
Missed a few consecutive beacons
Referenced by handleTimer().
{ EV << "Missed a few consecutive beacons -- AP is considered lost\n"; nb->fireChangeNotification(NF_L2_BEACON_LOST, NULL); //XXX use InterfaceEntry as detail, etc... }
void Ieee80211MgmtSTA::changeChannel | ( | int | channelNum | ) | [protected, virtual] |
Utility function: switches to the given radio channel.
Referenced by scanNextChannel(), startAssociation(), and startAuthentication().
{ EV << "Tuning to channel #" << channelNum << "\n"; // sending PHY_C_CONFIGURERADIO command to MAC PhyControlInfo *phyCtrl = new PhyControlInfo(); phyCtrl->setChannelNumber(channelNum); cMessage *msg = new cMessage("changeChannel", PHY_C_CONFIGURERADIO); msg->setControlInfo(phyCtrl); send(msg, "macOut"); }
void Ieee80211MgmtSTA::clearAPList | ( | ) | [protected, virtual] |
Utility function: clear the AP list, and cancel any pending authentications.
Referenced by processScanCommand().
void Ieee80211MgmtSTA::disassociate | ( | ) | [protected, virtual] |
Utility function: Cancel the existing association
Referenced by processDeauthenticateCommand(), processDisassociateCommand(), and processScanCommand().
{ EV << "Disassociating from AP address=" << assocAP.address << "\n"; ASSERT(isAssociated); isAssociated = false; delete cancelEvent(assocAP.beaconTimeoutMsg); assocAP.beaconTimeoutMsg = NULL; assocAP = AssociatedAPInfo(); // clear it }
Ieee80211DataFrame * Ieee80211MgmtSTA::encapsulate | ( | cPacket * | msg | ) | [protected, virtual] |
Utility function for handleUpperMessage()
Referenced by handleUpperMessage().
{ Ieee80211DataFrame *frame = new Ieee80211DataFrame(msg->getName()); // frame goes to the AP frame->setToDS(true); // receiver is the AP frame->setReceiverAddress(assocAP.address); // destination address is in address3 Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(msg->removeControlInfo()); frame->setAddress3(ctrl->getDest()); delete ctrl; frame->encapsulate(msg); return frame; }
void Ieee80211MgmtSTA::handleAssociationRequestFrame | ( | Ieee80211AssociationRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ dropManagementFrame(frame); }
void Ieee80211MgmtSTA::handleAssociationResponseFrame | ( | Ieee80211AssociationResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Received Association Response frame\n"; if (!assocTimeoutMsg) { EV << "No association in progress, ignoring frame\n"; delete frame; return; } // extract frame contents MACAddress address = frame->getTransmitterAddress(); int statusCode = frame->getBody().getStatusCode(); //XXX short aid; //XXX Ieee80211SupportedRatesElement supportedRates; delete frame; // look up AP data structure APInfo *ap = lookupAP(address); if (!ap) error("handleAssociationResponseFrame: AP not known: address=%s", address.str().c_str()); if (isAssociated) { EV << "Breaking existing association with AP address=" << assocAP.address << "\n"; isAssociated = false; delete cancelEvent(assocAP.beaconTimeoutMsg); assocAP.beaconTimeoutMsg = NULL; assocAP = AssociatedAPInfo(); } delete cancelEvent(assocTimeoutMsg); assocTimeoutMsg = NULL; if (statusCode!=SC_SUCCESSFUL) { EV << "Association failed with AP address=" << ap->address << "\n"; } else { EV << "Association successful, AP address=" << ap->address << "\n"; // change our state to "associated" isAssociated = true; (APInfo&)assocAP = (*ap); nb->fireChangeNotification(NF_L2_ASSOCIATED, NULL); //XXX detail: InterfaceEntry? assocAP.beaconTimeoutMsg = new cMessage("beaconTimeout", MK_BEACON_TIMEOUT); scheduleAt(simTime()+MAX_BEACONS_MISSED*assocAP.beaconInterval, assocAP.beaconTimeoutMsg); } // report back to agent sendAssociationConfirm(ap, statusCodeToPrimResultCode(statusCode)); }
void Ieee80211MgmtSTA::handleAuthenticationFrame | ( | Ieee80211AuthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ MACAddress address = frame->getTransmitterAddress(); int frameAuthSeq = frame->getBody().getSequenceNumber(); EV << "Received Authentication frame from address=" << address << ", seqNum=" << frameAuthSeq << "\n"; APInfo *ap = lookupAP(address); if (!ap) { EV << "AP not known, discarding authentication frame\n"; delete frame; return; } // what if already authenticated with AP if (ap->isAuthenticated) { EV << "AP already authenticated, ignoring frame\n"; delete frame; return; } // is authentication is in progress with this AP? if (!ap->authTimeoutMsg) { EV << "No authentication in progress with AP, ignoring frame\n"; delete frame; return; } // check authentication sequence number is OK if (frameAuthSeq != ap->authSeqExpected) { // wrong sequence number: send error and return EV << "Wrong sequence number, " << ap->authSeqExpected << " expected\n"; Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame("Auth-ERROR"); resp->getBody().setStatusCode(SC_AUTH_OUT_OF_SEQ); sendManagementFrame(resp, frame->getTransmitterAddress()); delete frame; // cancel timeout, send error to agent delete cancelEvent(ap->authTimeoutMsg); ap->authTimeoutMsg = NULL; sendAuthenticationConfirm(ap, PRC_REFUSED); //XXX or what resultCode? return; } // check if more exchanges are needed for auth to be complete int statusCode = frame->getBody().getStatusCode(); if (statusCode==SC_SUCCESSFUL && !frame->getBody().getIsLast()) { EV << "More steps required, sending another Authentication frame\n"; // more steps required, send another Authentication frame Ieee80211AuthenticationFrame *resp = new Ieee80211AuthenticationFrame("Auth"); resp->getBody().setSequenceNumber(frameAuthSeq+1); resp->getBody().setStatusCode(SC_SUCCESSFUL); // XXX frame length could be increased to account for challenge text length etc. sendManagementFrame(resp, address); ap->authSeqExpected += 2; } else { if (statusCode==SC_SUCCESSFUL) EV << "Authentication successful\n"; else EV << "Authentication failed\n"; // authentication completed ap->isAuthenticated = (statusCode==SC_SUCCESSFUL); delete cancelEvent(ap->authTimeoutMsg); ap->authTimeoutMsg = NULL; sendAuthenticationConfirm(ap, statusCodeToPrimResultCode(statusCode)); } delete frame; }
void Ieee80211MgmtSTA::handleBeaconFrame | ( | Ieee80211BeaconFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Received Beacon frame\n"; storeAPInfo(frame->getTransmitterAddress(), frame->getBody()); // if it is out associate AP, restart beacon timeout if (isAssociated && frame->getTransmitterAddress()==assocAP.address) { EV << "Beacon is from associated AP, restarting beacon timeout timer\n"; ASSERT(assocAP.beaconTimeoutMsg!=NULL); cancelEvent(assocAP.beaconTimeoutMsg); scheduleAt(simTime()+MAX_BEACONS_MISSED*assocAP.beaconInterval, assocAP.beaconTimeoutMsg); //APInfo *ap = lookupAP(frame->getTransmitterAddress()); //ASSERT(ap!=NULL); } delete frame; }
void Ieee80211MgmtSTA::handleCommand | ( | int | msgkind, |
cPolymorphic * | ctrl | ||
) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
{ if (dynamic_cast<Ieee80211Prim_ScanRequest *>(ctrl)) processScanCommand((Ieee80211Prim_ScanRequest *)ctrl); else if (dynamic_cast<Ieee80211Prim_AuthenticateRequest *>(ctrl)) processAuthenticateCommand((Ieee80211Prim_AuthenticateRequest *)ctrl); else if (dynamic_cast<Ieee80211Prim_DeauthenticateRequest *>(ctrl)) processDeauthenticateCommand((Ieee80211Prim_DeauthenticateRequest *)ctrl); else if (dynamic_cast<Ieee80211Prim_AssociateRequest *>(ctrl)) processAssociateCommand((Ieee80211Prim_AssociateRequest *)ctrl); else if (dynamic_cast<Ieee80211Prim_ReassociateRequest *>(ctrl)) processReassociateCommand((Ieee80211Prim_ReassociateRequest *)ctrl); else if (dynamic_cast<Ieee80211Prim_DisassociateRequest *>(ctrl)) processDisassociateCommand((Ieee80211Prim_DisassociateRequest *)ctrl); else if (ctrl) error("handleCommand(): unrecognized control info class `%s'", ctrl->getClassName()); else error("handleCommand(): control info is NULL"); delete ctrl; }
void Ieee80211MgmtSTA::handleDataFrame | ( | Ieee80211DataFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ sendUp(decapsulate(frame)); }
void Ieee80211MgmtSTA::handleDeauthenticationFrame | ( | Ieee80211DeauthenticationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Received Deauthentication frame\n"; const MACAddress& address = frame->getAddress3(); // source address APInfo *ap = lookupAP(address); if (!ap || !ap->isAuthenticated) { EV << "Unknown AP, or not authenticated with that AP -- ignoring frame\n"; delete frame; return; } if (ap->authTimeoutMsg) { delete cancelEvent(ap->authTimeoutMsg); ap->authTimeoutMsg = NULL; EV << "Cancelling pending authentication\n"; delete frame; return; } EV << "Setting isAuthenticated flag for that AP to false\n"; ap->isAuthenticated = false; }
void Ieee80211MgmtSTA::handleDisassociationFrame | ( | Ieee80211DisassociationFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Received Disassociation frame\n"; const MACAddress& address = frame->getAddress3(); // source address if (assocTimeoutMsg) { // pending association delete cancelEvent(assocTimeoutMsg); assocTimeoutMsg = NULL; } if (!isAssociated || address!=assocAP.address) { EV << "Not associated with that AP -- ignoring frame\n"; delete frame; return; } EV << "Setting isAssociated flag to false\n"; isAssociated = false; delete cancelEvent(assocAP.beaconTimeoutMsg); assocAP.beaconTimeoutMsg = NULL; }
void Ieee80211MgmtSTA::handleProbeRequestFrame | ( | Ieee80211ProbeRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ dropManagementFrame(frame); }
void Ieee80211MgmtSTA::handleProbeResponseFrame | ( | Ieee80211ProbeResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Received Probe Response frame\n"; storeAPInfo(frame->getTransmitterAddress(), frame->getBody()); delete frame; }
void Ieee80211MgmtSTA::handleReassociationRequestFrame | ( | Ieee80211ReassociationRequestFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ dropManagementFrame(frame); }
void Ieee80211MgmtSTA::handleReassociationResponseFrame | ( | Ieee80211ReassociationResponseFrame * | frame | ) | [protected, virtual] |
Implements Ieee80211MgmtBase.
{ EV << "Received Reassociation Response frame\n"; //TBD handle with the same code as Association Response? }
void Ieee80211MgmtSTA::handleTimer | ( | cMessage * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
{ if (msg->getKind()==MK_AUTH_TIMEOUT) { // authentication timed out APInfo *ap = (APInfo *)msg->getContextPointer(); EV << "Authentication timed out, AP address = " << ap->address << "\n"; // send back failure report to agent sendAuthenticationConfirm(ap, PRC_TIMEOUT); } else if (msg->getKind()==MK_ASSOC_TIMEOUT) { // association timed out APInfo *ap = (APInfo *)msg->getContextPointer(); EV << "Association timed out, AP address = " << ap->address << "\n"; // send back failure report to agent sendAssociationConfirm(ap, PRC_TIMEOUT); } else if (msg->getKind()==MK_SCAN_MAXCHANNELTIME) { // go to next channel during scanning bool done = scanNextChannel(); if (done) sendScanConfirm(); // send back response to agents' "scan" command delete msg; } else if (msg->getKind()==MK_SCAN_SENDPROBE) { // Active Scan: send a probe request, then wait for minChannelTime (11.1.3.2.2) delete msg; sendProbeRequest(); cMessage *timerMsg = new cMessage("minChannelTime", MK_SCAN_MINCHANNELTIME); scheduleAt(simTime()+scanning.minChannelTime, timerMsg); //XXX actually, we should start waiting after ProbeReq actually got transmitted } else if (msg->getKind()==MK_SCAN_MINCHANNELTIME) { // Active Scan: after minChannelTime, possibly listen for the remaining time until maxChannelTime delete msg; if (scanning.busyChannelDetected) { EV << "Busy channel detected during minChannelTime, continuing listening until maxChannelTime elapses\n"; cMessage *timerMsg = new cMessage("maxChannelTime", MK_SCAN_MAXCHANNELTIME); scheduleAt(simTime()+scanning.maxChannelTime - scanning.minChannelTime, timerMsg); } else { EV << "Channel was empty during minChannelTime, going to next channel\n"; bool done = scanNextChannel(); if (done) sendScanConfirm(); // send back response to agents' "scan" command } } else if (msg->getKind()==MK_BEACON_TIMEOUT) { // missed a few consecutive beacons beaconLost(); } else { error("internal error: unrecognized timer '%s'", msg->getName()); } }
void Ieee80211MgmtSTA::handleUpperMessage | ( | cPacket * | msg | ) | [protected, virtual] |
Implements abstract Ieee80211MgmtBase method
Implements Ieee80211MgmtBase.
{ Ieee80211DataFrame *frame = encapsulate(msg); sendOrEnqueue(frame); }
void Ieee80211MgmtSTA::initialize | ( | int | stage | ) | [protected, virtual] |
Reimplemented from Ieee80211MgmtBase.
{ Ieee80211MgmtBase::initialize(stage); if (stage==0) { isScanning = false; isAssociated = false; assocTimeoutMsg = NULL; nb = NotificationBoardAccess().get(); // determine numChannels (needed when we're told to scan "all" channels) //XXX find a better way than directly accessing channelControl cModule *cc = ChannelControl::get(); numChannels = cc->par("numChannels"); WATCH(isScanning); WATCH(isAssociated); WATCH(scanning); WATCH(assocAP); WATCH_LIST(apList); } }
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().
virtual int Ieee80211MgmtSTA::numInitStages | ( | ) | const [inline, protected, virtual] |
Reimplemented from Ieee80211MgmtBase.
{return 2;}
void Ieee80211MgmtSTA::processAssociateCommand | ( | Ieee80211Prim_AssociateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand(), and processReassociateCommand().
{ const MACAddress& address = ctrl->getAddress(); APInfo *ap = lookupAP(address); if (!ap) error("processAssociateCommand: AP not known: address = %s", address.str().c_str()); startAssociation(ap, ctrl->getTimeout()); }
void Ieee80211MgmtSTA::processAuthenticateCommand | ( | Ieee80211Prim_AuthenticateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
{ const MACAddress& address = ctrl->getAddress(); APInfo *ap = lookupAP(address); if (!ap) error("processAuthenticateCommand: AP not known: address = %s", address.str().c_str()); startAuthentication(ap, ctrl->getTimeout()); }
void Ieee80211MgmtSTA::processDeauthenticateCommand | ( | Ieee80211Prim_DeauthenticateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
{ const MACAddress& address = ctrl->getAddress(); APInfo *ap = lookupAP(address); if (!ap) error("processDeauthenticateCommand: AP not known: address = %s", address.str().c_str()); if (isAssociated && assocAP.address==address) disassociate(); if (ap->isAuthenticated) ap->isAuthenticated = false; // cancel possible pending authentication timer if (ap->authTimeoutMsg) { delete cancelEvent(ap->authTimeoutMsg); ap->authTimeoutMsg = NULL; } // create and send deauthentication request Ieee80211DeauthenticationFrame *frame = new Ieee80211DeauthenticationFrame("Deauth"); frame->getBody().setReasonCode(ctrl->getReasonCode()); sendManagementFrame(frame, address); }
void Ieee80211MgmtSTA::processDisassociateCommand | ( | Ieee80211Prim_DisassociateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
{ const MACAddress& address = ctrl->getAddress(); if (isAssociated && address==assocAP.address) { disassociate(); } else if (assocTimeoutMsg) { // pending association delete cancelEvent(assocTimeoutMsg); assocTimeoutMsg = NULL; } // create and send disassociation request Ieee80211DisassociationFrame *frame = new Ieee80211DisassociationFrame("Disass"); frame->getBody().setReasonCode(ctrl->getReasonCode()); sendManagementFrame(frame, address); }
void Ieee80211MgmtSTA::processReassociateCommand | ( | Ieee80211Prim_ReassociateRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
{ // treat the same way as association //XXX refine processAssociateCommand(ctrl); }
void Ieee80211MgmtSTA::processScanCommand | ( | Ieee80211Prim_ScanRequest * | ctrl | ) | [protected, virtual] |
Referenced by handleCommand().
{ EV << "Received Scan Request from agent, clearing AP list and starting scanning...\n"; if (isScanning) error("processScanCommand: scanning already in progress"); if (isAssociated) { disassociate(); } else if (assocTimeoutMsg) { EV << "Cancelling ongoing association process\n"; delete cancelEvent(assocTimeoutMsg); assocTimeoutMsg = NULL; } // clear existing AP list (and cancel any pending authentications) -- we want to start with a clean page clearAPList(); // fill in scanning state ASSERT(ctrl->getBSSType()==BSSTYPE_INFRASTRUCTURE); scanning.bssid = ctrl->getBSSID().isUnspecified() ? MACAddress::BROADCAST_ADDRESS : ctrl->getBSSID(); scanning.ssid = ctrl->getSSID(); scanning.activeScan = ctrl->getActiveScan(); scanning.probeDelay = ctrl->getProbeDelay(); scanning.channelList.clear(); scanning.minChannelTime = ctrl->getMinChannelTime(); scanning.maxChannelTime = ctrl->getMaxChannelTime(); ASSERT(scanning.minChannelTime <= scanning.maxChannelTime); // channel list to scan (default: all channels) for (int i=0; i<(int)ctrl->getChannelListArraySize(); i++) scanning.channelList.push_back(ctrl->getChannelList(i)); if (scanning.channelList.empty()) for (int i=0; i<numChannels; i++) scanning.channelList.push_back(i); // start scanning if (scanning.activeScan) nb->subscribe(this, NF_RADIOSTATE_CHANGED); scanning.currentChannelIndex = -1; // so we'll start with index==0 isScanning = true; scanNextChannel(); }
void Ieee80211MgmtSTA::receiveChangeNotification | ( | int | category, |
const cPolymorphic * | details | ||
) | [protected, virtual] |
Called by the NotificationBoard whenever a change occurs we're interested in
Implements INotifiable.
{ Enter_Method_Silent(); printNotificationBanner(category, details); // Note that we are only subscribed during scanning! if (category==NF_RADIOSTATE_CHANGED) { RadioState::State radioState = check_and_cast<RadioState *>(details)->getState(); if (radioState==RadioState::RECV) { EV << "busy radio channel detected during scanning\n"; scanning.busyChannelDetected = true; } } }
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().
{ // if we're already at the last channel, we're through if (scanning.currentChannelIndex==(int)scanning.channelList.size()-1) { EV << "Finished scanning last channel\n"; if (scanning.activeScan) nb->unsubscribe(this, NF_RADIOSTATE_CHANGED); isScanning = false; return true; // we're done } // tune to next channel int newChannel = scanning.channelList[++scanning.currentChannelIndex]; changeChannel(newChannel); scanning.busyChannelDetected = false; if (scanning.activeScan) { // Active Scan: first wait probeDelay, then send a probe. Listening // for minChannelTime or maxChannelTime takes place after that. (11.1.3.2) scheduleAt(simTime()+scanning.probeDelay, new cMessage("sendProbe", MK_SCAN_SENDPROBE)); } else { // Passive Scan: spend maxChannelTime on the channel (11.1.3.1) cMessage *timerMsg = new cMessage("maxChannelTime", MK_SCAN_MAXCHANNELTIME); scheduleAt(simTime()+scanning.maxChannelTime, timerMsg); } return false; }
void Ieee80211MgmtSTA::sendAssociationConfirm | ( | APInfo * | ap, |
int | resultCode | ||
) | [protected, virtual] |
Sends back result of association to the agent
Referenced by handleAssociationResponseFrame(), and handleTimer().
{ sendConfirm(new Ieee80211Prim_AssociateConfirm(), resultCode); }
void Ieee80211MgmtSTA::sendAuthenticationConfirm | ( | APInfo * | ap, |
int | resultCode | ||
) | [protected, virtual] |
Sends back result of authentication to the agent
Referenced by handleAuthenticationFrame(), and handleTimer().
{ Ieee80211Prim_AuthenticateConfirm *confirm = new Ieee80211Prim_AuthenticateConfirm(); confirm->setAddress(ap->address); sendConfirm(confirm, resultCode); }
void Ieee80211MgmtSTA::sendConfirm | ( | Ieee80211PrimConfirm * | confirm, |
int | resultCode | ||
) | [protected, virtual] |
Utility function: sends a confirmation to the agent
Referenced by sendAssociationConfirm(), sendAuthenticationConfirm(), and sendScanConfirm().
{ confirm->setResultCode(resultCode); cMessage *msg = new cMessage(confirm->getClassName()); msg->setControlInfo(confirm); send(msg, "agentOut"); }
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().
{ // frame goes to the specified AP frame->setToDS(true); frame->setReceiverAddress(address); //XXX set sequenceNumber? sendOrEnqueue(frame); }
void Ieee80211MgmtSTA::sendProbeRequest | ( | ) | [protected, virtual] |
Broadcasts a Probe Request
Referenced by handleTimer().
void Ieee80211MgmtSTA::sendScanConfirm | ( | ) | [protected, virtual] |
Sends back result of scanning to the agent
Referenced by handleTimer().
{ EV << "Scanning complete, found " << apList.size() << " APs, sending confirmation to agent\n"; // copy apList contents into a ScanConfirm primitive and send it back int n = apList.size(); Ieee80211Prim_ScanConfirm *confirm = new Ieee80211Prim_ScanConfirm(); confirm->setBssListArraySize(n); AccessPointList::iterator it = apList.begin(); //XXX filter for req'd bssid and ssid for (int i=0; i<n; i++, it++) { APInfo *ap = &(*it); Ieee80211Prim_BSSDescription& bss = confirm->getBssList(i); bss.setChannelNumber(ap->channel); bss.setBSSID(ap->address); bss.setSSID(ap->ssid.c_str()); bss.setSupportedRates(ap->supportedRates); bss.setBeaconInterval(ap->beaconInterval); bss.setRxPower(ap->rxPower); } sendConfirm(confirm, PRC_SUCCESS); }
void Ieee80211MgmtSTA::startAssociation | ( | APInfo * | ap, |
simtime_t | timeout | ||
) | [protected, virtual] |
Utility function: sends association request
Referenced by processAssociateCommand().
{ if (isAssociated || assocTimeoutMsg) error("startAssociation: already associated or association currently in progress"); if (!ap->isAuthenticated) error("startAssociation: not yet authenticated with AP address=", ap->address.str().c_str()); // switch to that channel changeChannel(ap->channel); // create and send association request Ieee80211AssociationRequestFrame *frame = new Ieee80211AssociationRequestFrame("Assoc"); //XXX set the following too? // string SSID // Ieee80211SupportedRatesElement supportedRates; sendManagementFrame(frame, ap->address); // schedule timeout ASSERT(assocTimeoutMsg==NULL); assocTimeoutMsg = new cMessage("assocTimeout", MK_ASSOC_TIMEOUT); assocTimeoutMsg->setContextPointer(ap); scheduleAt(simTime()+timeout, assocTimeoutMsg); }
void Ieee80211MgmtSTA::startAuthentication | ( | APInfo * | ap, |
simtime_t | timeout | ||
) | [protected, virtual] |
Utility function: sends authentication request
Referenced by processAuthenticateCommand().
{ if (ap->authTimeoutMsg) error("startAuthentication: authentication currently in progress with AP address=", ap->address.str().c_str()); if (ap->isAuthenticated) error("startAuthentication: already authenticated with AP address=", ap->address.str().c_str()); changeChannel(ap->channel); EV << "Sending initial Authentication frame with seqNum=1\n"; // create and send first authentication frame Ieee80211AuthenticationFrame *frame = new Ieee80211AuthenticationFrame("Auth"); frame->getBody().setSequenceNumber(1); //XXX frame length could be increased to account for challenge text length etc. sendManagementFrame(frame, ap->address); ap->authSeqExpected = 2; // schedule timeout ASSERT(ap->authTimeoutMsg==NULL); ap->authTimeoutMsg = new cMessage("authTimeout", MK_AUTH_TIMEOUT); ap->authTimeoutMsg->setContextPointer(ap); scheduleAt(simTime()+timeout, ap->authTimeoutMsg); }
int Ieee80211MgmtSTA::statusCodeToPrimResultCode | ( | int | statusCode | ) | [protected, virtual] |
Utility function: converts Ieee80211StatusCode (->frame) to Ieee80211PrimResultCode (->primitive)
Referenced by handleAssociationResponseFrame(), and handleAuthenticationFrame().
{
return statusCode==SC_SUCCESSFUL ? PRC_SUCCESS : PRC_REFUSED;
}
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().
{ APInfo *ap = lookupAP(address); if (ap) { EV << "AP address=" << address << ", SSID=" << body.getSSID() << " already in our AP list, refreshing the info\n"; } else { EV << "Inserting AP address=" << address << ", SSID=" << body.getSSID() << " into our AP list\n"; apList.push_back(APInfo()); ap = &apList.back(); } ap->channel = body.getChannelNumber(); ap->address = address; ap->ssid = body.getSSID(); ap->supportedRates = body.getSupportedRates(); ap->beaconInterval = body.getBeaconInterval(); //XXX where to get this from? //ap->rxPower = ... }
AccessPointList Ieee80211MgmtSTA::apList [protected] |
Referenced by clearAPList(), initialize(), lookupAP(), sendScanConfirm(), and storeAPInfo().
AssociatedAPInfo Ieee80211MgmtSTA::assocAP [protected] |
cMessage* Ieee80211MgmtSTA::assocTimeoutMsg [protected] |
bool Ieee80211MgmtSTA::isAssociated [protected] |
bool Ieee80211MgmtSTA::isScanning [protected] |
Referenced by initialize(), processScanCommand(), and scanNextChannel().
NotificationBoard* Ieee80211MgmtSTA::nb [protected] |
Referenced by beaconLost(), handleAssociationResponseFrame(), initialize(), processScanCommand(), and scanNextChannel().
int Ieee80211MgmtSTA::numChannels [protected] |
Referenced by initialize(), and processScanCommand().
ScanningInfo Ieee80211MgmtSTA::scanning [protected] |
Referenced by handleTimer(), initialize(), processScanCommand(), receiveChangeNotification(), scanNextChannel(), and sendProbeRequest().