i m stucked...

A

aki

Hi To you All,

I am trying to implement LCP in c++. I am using the below article
As reference...
The actual article "Efficiently Coding Communications Protocols in C
+
+"
is given at-
http://www.ddj.com/dept/cpp/193004231
I am facing some problems in understanding the article .
Can any one help me ...
I am marking in red the places I got stuck....

Implementing the Point-to-Point Protocol
Now we will look at a specific protocol, the Point-to-Point Protocol
(PPP) as defined in RFC-
1661. The Point-to-Point protocol is actually a family of protocols
sharing the same
encapsulation. A PPP implementation must include the Link Control
Protocol (LCP) and one or
more Network Control Protocols, one for each network protocol
supported. The most common
Network Control Protocol is the IP Control Protocol or IPCP. A PPP
implementation may also
include one or more authorization protocols. So the actual structure
of the PPP layer is a bit
more complex than the idealized structure shown above. The figure
below shows the structure
for the PPP protocol. It include of a single receiver and transmitter
that implement the message
encapsulation and message semantics. The LCP, each NCP and each
authorization protocol
include a context and their own state.

The State Pattern
The table shows the complexity of the protocol's behavior and coding
this state machine as C
case statements or if-else statements is a daunting task. However, the
protocol state is easily
implemented as a number of simple C++ classes using the State Pattern
described in Design
Patterns by Gamma, et al. shown below.

The LcpContext and LcpState Base Class
The class declaration for the LcpContext is show below. Note that we
have declared methods for
every event and action defined by the protocol. The LcpState class is
declared as a friend class so
that it has access to the private methods for executing actions and to
change the LcpContext's
state.
class LcpContext
{
public:
LcpContext(LcpState* initialState, PppTransmitter* transmitter);
~LcpContext();
// Events
void up();
void down();
void open();
void close();
void timeOut();
void timeOutRetryExpired();
void rcvConfigReqGood();
void rcvConfigReqBad();
void rcvConfigAck();
void rcvConfigNakRej();
void rcvTermReq();
void rcvTermAck();
void rcvUnknownCode();
void rcvCodeProtRejPermitted();
void rcvCodeProtRejCatastrophic();
void rcvEchoReq();
void rcvDiscardReq();
private:
friend class LcpState;
// Actions
void thisLayerUp();
void thisLayerDown();
void thisLayerStarted();
void thisLayerFinished();
void initRetryCount();
void zeroRetryCount();
void sendConfigReq();
void sendConfigAck();
void sendConfigNakRej();
void sendTermReq();
void sendTermAck();
void sendCodeRej();
void sendEchoReply();
void changeLcpState(LcpState* state);
LcpState* _state;
LcpTimer* _timer;
PppTransmitter* _transmitter;
};

The implementation of the event methods is simple. The event
processing is simply deferred to
the State object pointed to by _state.
void LcpContext::up()
{
_state->up(this); // why is this needed I donot understand...

}

The action methods are also simple, deferring the processing to a
transmitter or timer object.
This decouples the State objects from the PppTransmitter, PppReceiver,
and LcpTimer classes so
that the state classes can be easily used for a number of PPP
applications such as PPP over
Ethernet (PPPOE) or Packet Over SONET (POS):
void LcpContext::sendConfigReq()
{
_trasnmitter->sendConfigReq(this);
}

The declaration of the base class LcpState is shown below. Again, we
have declared methods for
each of the events listed in the PPP LCP specification in RFC-1661.
class LcpState
{
public:
virtual ~LcpState();
virtual void up(LcpContext* lcpContext);
virtual void down(LcpContext* lcpContext);
virtual void open(LcpContext* lcpContext);
virtual void close(LcpContext* lcpContext);
virtual void timeOut(LcpContext* lcpContext);
virtual void recvConfigReq(LcpContext* lcpContext);
virtual void recvConfigAck(LcpContext* lcpContext);
virtual void recvConfigNak(LcpContext* lcpContext);
virtual void recvTermReq(LcpContext* lcpContext);
virtual void recvTermAck(LcpContext* lcpContext);
virtual void recvUnknownCode(LcpContext* lcpContext);
virtual void recvCodeRej(LcpContext* lcpContext);
virtual void recvProtRej(LcpContext* lcpContext);
virtual void recvEchoReq(LcpContext* lcpContext);
virtual void recvEchoReply(LcpContext* lcpContext);
virtual void recvDiscardReq(LcpContext* lcpContext);
protected:
void changeLcpState(LcpContext* lcpContext, LcpState* state); // why
defined in protected
};

- 10 -
Each concrete state class will override the default event methods
defined by the LcpState base
class except when a specific event is invalid for that state. These
cases are shown indicated by
blank entries in the state table. In these cases, we simply log the
error.
LcpState::up(LcpContext* lcpContext()
{
Logger::log("Invalid LCP Event up Receved");
}

The Concrete LcpState Classes
We now go on to define concrete LcpState classes for each of the ten
states specified in RFC-
161. In each of the concrete LcpState classes we simply define methods
to handle each of the
valid events that can be received in that state. These methods simply
execute the actions defined
in the PPP LCP State Table. For example, here is the rcvConfigAck
method for the
AckSentLcpState class:
AckSentLcpState::rcvConfigAck(LcpContext* lcpContext)
{
lcpContext->initRetryCount();
lcpContext->thisLayerUp();
changeLcpState(lcpContext, getInstance::OpenedLcpState()); // what
does getinstance class contains... and how are state changing...

}

Some of my doubts-

I was trying to check the concept using sample code but facing
problem in linking all modules....

#include<iostream>
using namespace std;
enum
{initial,starting,closed,stopped,closing,stopping,request_sent,ack_received,ack_sent,opened};

class Lcpstate;
class Lcp{
public:
void open();
friend class LcpState;
void recvconfigreq();
void sendconfigack();
Lcpstate* state;
void changestate(Lcpstate *state);
}

class Lcpstate{
public:
virtual void recvconfigreq(Lcp *obj);

protected:
void changestate( Lcp* obj,Lcpstate *state);
}

class acksent: public Lcpstate{
void recvconfigreq(Lcp *obj);

};

Class getinstance{
Public:
Void Initial();
Void Starting();
Void opened();
-// all state functions...

};

void getinstance::eek:pened()
{state=opened;

};

void Lcp::recvconfigreq()

{
state->recvconfigreq(this);

}

void Lcp:: sendconfigack()
{
cout<<"ack sent";

}

void acksent:: recvconfigreq(Lcp*obj)
{
obj->sendconfigack();
changestate(obj,getinstance::eek:pened());

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top