Ieee80211MgmtSTA Class Reference

#include <Ieee80211MgmtSTA.h>

Inheritance diagram for Ieee80211MgmtSTA:

Ieee80211MgmtBase PassiveQueueBase INotifiable IPassiveQueue

List of all members.


Detailed Description

Used in 802.11 infrastructure mode: handles management frames for a station (STA). See corresponding NED file for a detailed description.

Author:
Andras Varga

Protected Types

typedef std::list< APInfoAccessPointList

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 APInfolookupAP (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

NotificationBoardnb
int numChannels
bool isScanning
ScanningInfo scanning
AccessPointList apList
bool isAssociated
cMessage * assocTimeoutMsg
AssociatedAPInfo assocAP

Classes

struct  APInfo
struct  AssociatedAPInfo
struct  ScanningInfo

Member Typedef Documentation

typedef std::list<APInfo> Ieee80211MgmtSTA::AccessPointList [protected]


Member Function Documentation

virtual int Ieee80211MgmtSTA::numInitStages (  )  const [inline, protected, virtual]

Reimplemented from Ieee80211MgmtBase.

00106 {return 2;}

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().

00551 {
00552     return statusCode==SC_SUCCESSFUL ? PRC_SUCCESS : PRC_REFUSED;
00553 }

void Ieee80211MgmtSTA::handleDataFrame ( Ieee80211DataFrame *  frame  )  [protected, virtual]

Implements Ieee80211MgmtBase.

00556 {
00557     sendUp(decapsulate(frame));
00558 }

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]

Implements Ieee80211MgmtBase.

00664 {
00665     dropManagementFrame(frame);
00666 }

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]

Implements Ieee80211MgmtBase.

00726 {
00727     dropManagementFrame(frame);
00728 }

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]

Implements Ieee80211MgmtBase.

00781 {
00782     dropManagementFrame(frame);
00783 }

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 }


Member Data Documentation

Referenced by initialize(), and processScanCommand().

bool Ieee80211MgmtSTA::isScanning [protected]

cMessage* Ieee80211MgmtSTA::assocTimeoutMsg [protected]


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5