INET Framework for OMNeT++/OMNEST
Ieee80211AgentSTA Class Reference

#include <Ieee80211AgentSTA.h>

Inheritance diagram for Ieee80211AgentSTA:
INotifiable

List of all members.

Protected Member Functions

virtual int numInitStages () const
virtual void initialize (int)
virtual void handleMessage (cMessage *msg)
virtual void handleTimer (cMessage *msg)
virtual void handleResponse (cMessage *msg)
virtual void receiveChangeNotification (int category, const cPolymorphic *details)
virtual void sendRequest (Ieee80211PrimRequest *req)
virtual int chooseBSS (Ieee80211Prim_ScanConfirm *resp)
virtual void dumpAPList (Ieee80211Prim_ScanConfirm *resp)
virtual void sendScanRequest ()
virtual void sendAuthenticateRequest (const MACAddress &address)
virtual void sendDeauthenticateRequest (const MACAddress &address, int reasonCode)
virtual void sendAssociateRequest (const MACAddress &address)
virtual void sendReassociateRequest (const MACAddress &address)
virtual void sendDisassociateRequest (const MACAddress &address, int reasonCode)
virtual void processScanConfirm (Ieee80211Prim_ScanConfirm *resp)
virtual void processAuthenticateConfirm (Ieee80211Prim_AuthenticateConfirm *resp)
virtual void processAssociateConfirm (Ieee80211Prim_AssociateConfirm *resp)
virtual void processReassociateConfirm (Ieee80211Prim_ReassociateConfirm *resp)

Protected Attributes

bool activeScan
std::vector< int > channelsToScan
simtime_t probeDelay
simtime_t minChannelTime
simtime_t maxChannelTime
simtime_t authenticationTimeout
simtime_t associationTimeout

Detailed Description

Used in 802.11 infrastructure mode: in a station (STA), this module controls channel scanning, association and handovers, by sending commands (e.g. Ieee80211Prim_ScanRequest) to the management getModule(Ieee80211MgmtSTA).

See corresponding NED file for a detailed description.

Author:
Andras Varga

Member Function Documentation

int Ieee80211AgentSTA::chooseBSS ( Ieee80211Prim_ScanConfirm *  resp) [protected, virtual]

Choose one AP from the list to associate with

Referenced by processScanConfirm().

{
    if (resp->getBssListArraySize()==0)
        return -1;

    // here, just choose the one with the greatest receive power
    // TODO and which supports a good data rate we support
    int bestIndex = 0;
    for (int i=0; i<(int)resp->getBssListArraySize(); i++)
        if (resp->getBssList(i).getRxPower() > resp->getBssList(bestIndex).getRxPower())
            bestIndex = i;
    return bestIndex;
}
void Ieee80211AgentSTA::dumpAPList ( Ieee80211Prim_ScanConfirm *  resp) [protected, virtual]

Referenced by processScanConfirm().

{
    EV << "Received AP list:\n";
    for (int i=0; i<(int)resp->getBssListArraySize(); i++)
    {
        Ieee80211Prim_BSSDescription& bssDesc = resp->getBssList(i);
        EV << "    " << i << ". "
           << " address=" << bssDesc.getBSSID()
           << " channel=" << bssDesc.getChannelNumber()
           << " SSID=" << bssDesc.getSSID()
           << " beaconIntvl=" << bssDesc.getBeaconInterval()
           << " rxPower=" << bssDesc.getRxPower()
           << endl;
        // later: supportedRates
    }
}
void Ieee80211AgentSTA::handleMessage ( cMessage *  msg) [protected, virtual]

Overridden cSimpleModule method

{
    if (msg->isSelfMessage())
        handleTimer(msg);
    else
        handleResponse(msg);
}
void Ieee80211AgentSTA::handleResponse ( cMessage *  msg) [protected, virtual]

Handle responses from mgmgt

Referenced by handleMessage().

{
    cPolymorphic *ctrl = msg->removeControlInfo();
    delete msg;

    EV << "Processing confirmation from mgmt: " << ctrl->getClassName() << "\n";

    if (dynamic_cast<Ieee80211Prim_ScanConfirm *>(ctrl))
        processScanConfirm((Ieee80211Prim_ScanConfirm *)ctrl);
    else if (dynamic_cast<Ieee80211Prim_AuthenticateConfirm *>(ctrl))
        processAuthenticateConfirm((Ieee80211Prim_AuthenticateConfirm *)ctrl);
    else if (dynamic_cast<Ieee80211Prim_AssociateConfirm *>(ctrl))
        processAssociateConfirm((Ieee80211Prim_AssociateConfirm *)ctrl);
    else if (dynamic_cast<Ieee80211Prim_ReassociateConfirm *>(ctrl))
        processReassociateConfirm((Ieee80211Prim_ReassociateConfirm *)ctrl);
    else if (ctrl)
        error("handleResponse(): unrecognized control info class `%s'", ctrl->getClassName());
    else
        error("handleResponse(): control info is NULL");
    delete ctrl;
}
void Ieee80211AgentSTA::handleTimer ( cMessage *  msg) [protected, virtual]

Handle timers

Referenced by handleMessage().

{
    if (msg->getKind()==MK_STARTUP)
    {
        EV << "Starting up\n";
        sendScanRequest();
        delete msg;
    }
    else
    {
        error("internal error: unrecognized timer '%s'", msg->getName());
    }
}
void Ieee80211AgentSTA::initialize ( int  stage) [protected, virtual]
{
    if (stage==0)
    {
        // read parameters
        activeScan = par("activeScan");
        probeDelay = par("probeDelay");
        minChannelTime = par("minChannelTime");
        maxChannelTime = par("maxChannelTime");
        authenticationTimeout = par("authenticationTimeout");
        associationTimeout = par("associationTimeout");
        cStringTokenizer tokenizer(par("channelsToScan"));
        const char *token;
        while ((token = tokenizer.nextToken())!=NULL)
            channelsToScan.push_back(atoi(token));

        NotificationBoard *nb = NotificationBoardAccess().get();
        nb->subscribe(this, NF_L2_BEACON_LOST);

        // start up: send scan request
        scheduleAt(simTime()+uniform(0,maxChannelTime), new cMessage("startUp", MK_STARTUP));
    }
}
virtual int Ieee80211AgentSTA::numInitStages ( ) const [inline, protected, virtual]
{return 2;}
void Ieee80211AgentSTA::processAssociateConfirm ( Ieee80211Prim_AssociateConfirm *  resp) [protected, virtual]

Referenced by handleResponse().

{
    if (resp->getResultCode()!=PRC_SUCCESS)
    {
        EV << "Association error\n";

        // try scanning again, maybe we'll have better luck next time, possibly with a different AP
        EV << "Going back to scanning\n";
        sendScanRequest();
    }
    else
    {
        EV << "Association successful\n";
        // we are happy!
        getParentModule()->getParentModule()->bubble("Associated with AP");
    }
}
void Ieee80211AgentSTA::processAuthenticateConfirm ( Ieee80211Prim_AuthenticateConfirm *  resp) [protected, virtual]

Referenced by handleResponse().

{
    if (resp->getResultCode()!=PRC_SUCCESS)
    {
        EV << "Authentication error\n";

        // try scanning again, maybe we'll have better luck next time, possibly with a different AP
        EV << "Going back to scanning\n";
        sendScanRequest();
    }
    else
    {
        EV << "Authentication successful, let's try to associate\n";
        sendAssociateRequest(resp->getAddress());
    }
}
void Ieee80211AgentSTA::processReassociateConfirm ( Ieee80211Prim_ReassociateConfirm *  resp) [protected, virtual]

Referenced by handleResponse().

{
    // treat the same way as AssociateConfirm
    if (resp->getResultCode()!=PRC_SUCCESS)
    {
        EV << "Reassociation error\n";
        EV << "Going back to scanning\n";
        sendScanRequest();
    }
    else
    {
        EV << "Reassociation successful\n";
        // we are happy!
    }
}
void Ieee80211AgentSTA::processScanConfirm ( Ieee80211Prim_ScanConfirm *  resp) [protected, virtual]

Processing Confirm primitives

Referenced by handleResponse().

{
    // choose best AP
    int bssIndex = chooseBSS(resp);
    if (bssIndex==-1)
    {
        EV << "No (suitable) AP found, continue scanning\n";
        sendScanRequest();
        return;
    }

    dumpAPList(resp);

    Ieee80211Prim_BSSDescription& bssDesc = resp->getBssList(bssIndex);
    EV << "Chosen AP address=" << bssDesc.getBSSID() << " from list, starting authentication\n";
    sendAuthenticateRequest(bssDesc.getBSSID());
}
void Ieee80211AgentSTA::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [protected, virtual]

Redefined from INotifiable; called by NotificationBoard

Implements INotifiable.

{
    Enter_Method_Silent();
    printNotificationBanner(category, details);

    if (category == NF_L2_BEACON_LOST)
    {
        //XXX should check details if it's about this NIC
        EV << "beacon lost, starting scanning again\n";
        getParentModule()->getParentModule()->bubble("Beacon lost!");
        //sendDisassociateRequest();
        sendScanRequest();
    }
}
void Ieee80211AgentSTA::sendAssociateRequest ( const MACAddress address) [protected, virtual]

Referenced by processAuthenticateConfirm().

{
    EV << "Sending AssociateRequest primitive to mgmt\n";
    Ieee80211Prim_AssociateRequest *req = new Ieee80211Prim_AssociateRequest();
    req->setAddress(address);
    req->setTimeout(associationTimeout);
    sendRequest(req);
}
void Ieee80211AgentSTA::sendAuthenticateRequest ( const MACAddress address) [protected, virtual]

Referenced by processScanConfirm().

{
    EV << "Sending AuthenticateRequest primitive to mgmt\n";
    Ieee80211Prim_AuthenticateRequest *req = new Ieee80211Prim_AuthenticateRequest();
    req->setAddress(address);
    req->setTimeout(authenticationTimeout);
    sendRequest(req);
}
void Ieee80211AgentSTA::sendDeauthenticateRequest ( const MACAddress address,
int  reasonCode 
) [protected, virtual]
{
    EV << "Sending DeauthenticateRequest primitive to mgmt\n";
    Ieee80211Prim_DeauthenticateRequest *req = new Ieee80211Prim_DeauthenticateRequest();
    req->setAddress(address);
    req->setReasonCode(reasonCode);
    sendRequest(req);
}
void Ieee80211AgentSTA::sendDisassociateRequest ( const MACAddress address,
int  reasonCode 
) [protected, virtual]
{
    EV << "Sending DisassociateRequest primitive to mgmt\n";
    Ieee80211Prim_DisassociateRequest *req = new Ieee80211Prim_DisassociateRequest();
    req->setAddress(address);
    req->setReasonCode(reasonCode);
    sendRequest(req);
}
void Ieee80211AgentSTA::sendReassociateRequest ( const MACAddress address) [protected, virtual]
{
    EV << "Sending ReassociateRequest primitive to mgmt\n";
    Ieee80211Prim_ReassociateRequest *req = new Ieee80211Prim_ReassociateRequest();
    req->setAddress(address);
    req->setTimeout(associationTimeout);
    sendRequest(req);
}
void Ieee80211AgentSTA::sendRequest ( Ieee80211PrimRequest *  req) [protected, virtual]

Referenced by sendAssociateRequest(), sendAuthenticateRequest(), sendDeauthenticateRequest(), sendDisassociateRequest(), sendReassociateRequest(), and sendScanRequest().

{
    cMessage *msg = new cMessage(req->getClassName());
    msg->setControlInfo(req);
    send(msg, "mgmtOut");
}
void Ieee80211AgentSTA::sendScanRequest ( ) [protected, virtual]

Sending of Request primitives

Referenced by handleTimer(), processAssociateConfirm(), processAuthenticateConfirm(), processReassociateConfirm(), processScanConfirm(), and receiveChangeNotification().

{
    EV << "Sending ScanRequest primitive to mgmt\n";
    Ieee80211Prim_ScanRequest *req = new Ieee80211Prim_ScanRequest();
    req->setBSSType(BSSTYPE_INFRASTRUCTURE);
    req->setActiveScan(activeScan);
    req->setProbeDelay(probeDelay);
    req->setMinChannelTime(minChannelTime);
    req->setMaxChannelTime(maxChannelTime);
    req->setChannelListArraySize(channelsToScan.size());
    for (int i=0; i<(int)channelsToScan.size(); i++)
        req->setChannelList(i, channelsToScan[i]);
    //XXX BSSID, SSID are left at default ("any")

    sendRequest(req);
}

Member Data Documentation

Referenced by initialize(), and sendScanRequest().

std::vector<int> Ieee80211AgentSTA::channelsToScan [protected]

Referenced by initialize(), and sendScanRequest().

simtime_t Ieee80211AgentSTA::maxChannelTime [protected]

Referenced by initialize(), and sendScanRequest().

simtime_t Ieee80211AgentSTA::minChannelTime [protected]

Referenced by initialize(), and sendScanRequest().

simtime_t Ieee80211AgentSTA::probeDelay [protected]

Referenced by initialize(), and sendScanRequest().


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