More work on interface and layer 2.

git-svn-id: http://yate.null.ro/svn/yate/trunk@767 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2006-05-02 07:12:18 +00:00
parent 1d9401f345
commit 50d4790b72
4 changed files with 175 additions and 30 deletions

View File

@ -40,12 +40,19 @@ void SignallingInterface::attach(SignallingReceiver* receiver)
bool SignallingInterface::control(Operation oper, NamedList* params)
{
DDebug(engine(),DebugInfo,"Unhandled SignallingInterface::control(%d,%p) [%p]",
oper,params,this);
return false;
}
bool SignallingInterface::receivedPacket()
bool SignallingInterface::receivedPacket(const DataBlock& packet)
{
return m_receiver && m_receiver->receivedPacket();
return m_receiver && m_receiver->receivedPacket(packet);
}
bool SignallingInterface::notify(Notification event)
{
return m_receiver && m_receiver->notify(event);
}
@ -61,4 +68,10 @@ void SignallingReceiver::attach(SignallingInterface* iface)
Debug("STUB",DebugWarn,"Please implement SignallingReceiver::attach()");
}
bool SignallingReceiver::notify(SignallingInterface::Notification event)
{
DDebug(engine(),DebugInfo,"Unhandled SignallingReceiver::notify(%d) [%p]",event,this);
return false;
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -26,19 +26,93 @@
using namespace TelEngine;
bool SS7MTP2::receivedMSU()
SS7MTP2::SS7MTP2()
: Mutex(false), m_bsn(0), m_fsn(0), m_bib(false), m_fib(false)
{
Debug("STUB",DebugWarn,"Please implement SS7MTP2::receivedMSU()");
}
bool SS7MTP2::transmitMSU()
// Transmit a MSU retaining a copy for retransmissions
bool SS7MTP2::transmitMSU(const DataBlock& msu)
{
Debug("STUB",DebugWarn,"Please implement SS7MTP2::transmitMSU()");
if (msu.length() < 3) {
Debug(engine(),DebugMild,"Asked to send MSU of length %u [%p]",
msu.length(),this);
return false;
}
XDebug(engine(),DebugAll,"SS7MTP2::transmitMSU(%p) len=%u [%p]",
&msu,msu.length(),this);
// if we don't have an attached interface don't bother
if (!iface())
return false;
DataBlock* packet = new DataBlock(0,3);
*packet += msu;
// set BSN+BIB, FSN+FIB, LENGTH in the 3 extra bytes
unsigned char* buf = (unsigned char*)packet->data();
buf[2] = (msu.length() > 0x3f) ? 0x3f : msu.length() & 0x3f;
// lock the object so we can safely use member variables
Lock lock(this);
buf[0] = m_bib ? m_bsn | 0x80 : m_bsn;
buf[1] = m_fib ? m_fsn | 0x80 : m_fsn;
++m_fsn;
m_queue.append(packet);
return transmitPacket(*packet,false);
}
bool SS7MTP2::receivedPacket()
// Decode a received packet into signalling units
bool SS7MTP2::receivedPacket(const DataBlock& packet)
{
Debug("STUB",DebugWarn,"Please implement SS7MTP2::receivedPacket()");
if (packet.length() < 3) {
XDebug(engine(),DebugMild,"Received short packet of length %u [%p]",
packet.length(),this)
return false;
}
const unsigned char* buf = (const unsigned char*)packet.data();
unsigned int len = buf[2] & 0x3f;
if ((len == 0x3f) && (packet.length() > 0x42))
len = packet.length() - 3;
else if (len != (packet.length() - 3)) {
XDebug(engine(),DebugMild,"Received packet with length indicator %u but length %u [%p]",
len,packet.length(),this);
return false;
}
bool ok = true;
// packet length is valid, check sequence numbers
unsigned char bsn = buf[0] & 0x7f;
bool bib = (buf[0] & 0x80) != 0;
unsigned char fsn = buf[1] & 0x7f;
bool fib = (buf[1] & 0x80) != 0;
//TODO: implement Q.703 6.3.1
switch (len) {
case 2:
// processLSSU(buf[3]);
// break;
case 1:
processLSSU(buf[3]);
return ok;
case 0:
processFISU();
return ok;
}
DataBlock msu((void*)(buf+3),len,false);
ok = receivedMSU(msu);
msu.clear(false);
return ok;
}
// Process incoming FISU
void SS7MTP2::processFISU()
{
}
// Process incoming LSSU
void SS7MTP2::processLSSU(unsigned int status)
{
Debug("STUB",DebugWarn,"Please implement SS7MTP2::processLSSU()");
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -32,7 +32,7 @@ void SS7MTP3::attach(SS7Layer2* link)
SignallingComponent::insert(link);
}
bool SS7MTP3::receivedMSU()
bool SS7MTP3::receivedMSU(const DataBlock& msu)
{
Debug("STUB",DebugWarn,"Please implement SS7MTP3::receivedMSU()");
}

View File

@ -244,6 +244,22 @@ public:
Query = 0xc0
};
/**
* Interface generated notifications
*/
enum Notification {
HardwareError,
TxClockError,
RxClockError,
AlignError,
CksumError,
TxOversize,
RxOversize,
TxOverflow,
RxOverflow,
TxUnderrun,
};
/**
* Destructor, stops and detaches the interface
*/
@ -276,15 +292,26 @@ public:
protected:
/**
* Transmit a packet over the hardware interface
* @param packet Packet data to send
* @param repeat Continuously send a copy of the packet while no other
* data is available for transmission
* @return True if the interface accepted the packet
*/
virtual bool transmitPacket() = 0;
virtual bool transmitPacket(const DataBlock& packet, bool repeat) = 0;
/**
* Push a received Signalling Packet up the protocol stack
* Push a valid received Signalling Packet up the protocol stack.
* The starting and ending flags and any CRC are not part of the data.
* @return True if packet was successfully delivered to the receiver
*/
bool receivedPacket();
bool receivedPacket(const DataBlock& packet);
/**
* Generate a notification event to the attached receiver
* @param event Notification event to be reported
* @return True if notification was accepted by the receiver
*/
bool notify(Notification event);
private:
SignallingReceiver* m_receiver;
@ -330,16 +357,26 @@ public:
protected:
/**
* Send a packet to the attached interface for transmission
* @param packet Packet data to send
* @param repeat Continuously send a copy of the packet while no other
* data is available for transmission
* @return True if the interface accepted the packet
*/
inline bool transmitPacket()
{ return m_interface && m_interface->transmitPacket(); }
inline bool transmitPacket(const DataBlock& packet, bool repeat)
{ return m_interface && m_interface->transmitPacket(packet,repeat); }
/**
* Process a Signalling Packet received by the interface
* @return True if message was successfully processed
*/
virtual bool receivedPacket() = 0;
virtual bool receivedPacket(const DataBlock& packet) = 0;
/**
* Process a notification generated by the attached interface
* @param event Notification event reported by the interface
* @return True if notification was processed
*/
virtual bool notify(SignallingInterface::Notification event);
private:
SignallingInterface* m_interface;
@ -468,9 +505,10 @@ public:
protected:
/**
* Process a MSU received from the Layer 2 component
* @param msu Message data, starting with Service Indicator Octet
* @return True if the MSU was processed
*/
virtual bool receivedMSU() = 0;
virtual bool receivedMSU(const DataBlock& msu) = 0;
};
/**
@ -487,10 +525,11 @@ public:
};
/**
* Push a Message Signalling Unit down the protocol stack
* Push a Message Signal Unit down the protocol stack
* @param msu Message data, starting with Service Indicator Octet
* @return True if message was successfully queued
*/
virtual bool transmitMSU() = 0;
virtual bool transmitMSU(const DataBlock& msu) = 0;
/**
* Attach a Layer 2 user component to the data link
@ -508,11 +547,12 @@ public:
protected:
/**
* Push a received Message Signalling Unit up the protocol stack
* Push a received Message Signal Unit up the protocol stack
* @param msu Message data, starting with Service Indicator Octet
* @return True if message was successfully delivered to the user component
*/
inline bool receivedMSU()
{ return m_l2user && m_l2user->receivedMSU(); }
inline bool receivedMSU(const DataBlock& msu)
{ return m_l2user && m_l2user->receivedMSU(msu); }
private:
SS7L2User* m_l2user;
@ -633,28 +673,45 @@ class YSS7_API SS7M3UA : public SS7Layer3, public SIGTRAN
* Q.703 SS7 Layer 2 (Data Link) implementation on top of a hardware interface
* @short SS7 Layer 2 implementation on top of a hardware interface
*/
class YSS7_API SS7MTP2 : public SS7Layer2, public SignallingReceiver
class YSS7_API SS7MTP2 : public SS7Layer2, public SignallingReceiver, public Mutex
{
public:
/**
* Push a Message Signalling Unit down the protocol stack
* Constructor
*/
SS7MTP2();
/**
* Push a Message Signal Unit down the protocol stack
* @return True if message was successfully queued
*/
virtual bool transmitMSU();
virtual bool transmitMSU(const DataBlock& msu);
protected:
/**
* Process a MSU received from the Layer 2 component
* @return True if the MSU was processed
*/
virtual bool receivedMSU();
/**
* Process a Signalling Packet received by the hardware interface
* @return True if message was successfully processed
*/
virtual bool receivedPacket();
virtual bool receivedPacket(const DataBlock& packet);
/**
* Process a received Fill-In Signal Unit
*/
virtual void processFISU();
/**
* Process a received Link Status Signal Unit
*/
virtual void processLSSU(unsigned int status);
private:
// sent but yet unacknowledged packets
ObjList m_queue;
// backward and forward sqeuence numbers
unsigned char m_bsn, m_fsn;
// backward and forward indicator bits
bool m_bib, m_fib;
};
/**
@ -673,9 +730,10 @@ public:
protected:
/**
* Process a MSU received from the Layer 2 component
* @param msu Message data, starting with Service Indicator Octet
* @return True if the MSU was processed
*/
virtual bool receivedMSU();
virtual bool receivedMSU(const DataBlock& msu);
ObjList m_links;
};