Commit 73ff04a1 authored by Pavel Vainerman's avatar Pavel Vainerman

(unet2): Реализовал логику переключение каналов (основной-резервный)

parent 596b2795
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
priority - приоритет сообщения об изменении данного датчика priority - приоритет сообщения об изменении данного датчика
textname - текстовое имя датчика textname - текстовое имя датчика
--> -->
<nodes port="2809" unet_broadcast_ip="192.168.1.255"> <nodes port="2809" unet_broadcast_ip="192.168.1.255" unet_broadcast_ip2="192.168.122.255">
<item infserver="InfoServer" ip="127.0.0.1" name="LocalhostNode" textname="Локальный узел" unet_ignore="0" unet_port="2048"> <item infserver="InfoServer" ip="127.0.0.1" name="LocalhostNode" textname="Локальный узел" unet_ignore="0" unet_port="2048">
<iocards> <iocards>
<item card="1" name="DI32"/> <item card="1" name="DI32"/>
......
...@@ -122,6 +122,8 @@ sender2(0) ...@@ -122,6 +122,8 @@ sender2(0)
sender = new UNetSender(h,p,shm,s_field,s_fvalue,ic); sender = new UNetSender(h,p,shm,s_field,s_fvalue,ic);
sender->setSendPause(sendpause); sender->setSendPause(sendpause);
try
{
// создаём "писателя" для второго канала если задан // создаём "писателя" для второго канала если задан
if( !h2.empty() ) if( !h2.empty() )
{ {
...@@ -129,6 +131,14 @@ sender2(0) ...@@ -129,6 +131,14 @@ sender2(0)
sender2 = new UNetSender(h2,p2,shm,s_field,s_fvalue,ic); sender2 = new UNetSender(h2,p2,shm,s_field,s_fvalue,ic);
sender2->setSendPause(sendpause); sender2->setSendPause(sendpause);
} }
}
catch(...)
{
// т.е. это "резервный канал", то игнорируем ошибку его создания
// при запуске "интерфейс" может быть и не доступен...
sender2 = 0;
dlog[Debug::CRIT] << myname << "(ignore): DON`T CREATE 'UNetSender' for " << h2 << ":" << p2 << endl;
}
continue; continue;
} }
...@@ -210,10 +220,16 @@ sender2(0) ...@@ -210,10 +220,16 @@ sender2(0)
r->setMaxProcessingCount(maxProcessingCount); r->setMaxProcessingCount(maxProcessingCount);
r->setRespondID(resp_id); r->setRespondID(resp_id);
r->setLostPacketsID(lp_id); r->setLostPacketsID(lp_id);
r->connectEvent( sigc::mem_fun(this, &UNetExchange::receiverEvent) );
UNetReceiver* r2 = 0; UNetReceiver* r2 = 0;
try
{
if( !h2.empty() ) // создаём читателя впо второму каналу if( !h2.empty() ) // создаём читателя впо второму каналу
{ {
dlog[Debug::INFO] << myname << "(init): add reserv receiver "
<< h2 << ":" << p2 << endl;
r2 = new UNetReceiver(h2,p2,shm); r2 = new UNetReceiver(h2,p2,shm);
// т.к. это резервный канал (по началу блокируем его) // т.к. это резервный канал (по началу блокируем его)
...@@ -227,6 +243,15 @@ sender2(0) ...@@ -227,6 +243,15 @@ sender2(0)
r2->setMaxProcessingCount(maxProcessingCount); r2->setMaxProcessingCount(maxProcessingCount);
r2->setRespondID(resp2_id); r2->setRespondID(resp2_id);
r2->setLostPacketsID(lp2_id); r2->setLostPacketsID(lp2_id);
r2->connectEvent( sigc::mem_fun(this, &UNetExchange::receiverEvent) );
}
}
catch(...)
{
// т.е. это "резервный канал", то игнорируем ошибку его создания
// при запуске "интерфейс" может быть и не доступен...
r2 = 0;
dlog[Debug::CRIT] << myname << "(ignore): DON`T CREATE 'UNetReceiver' for " << h2 << ":" << p2 << endl;
} }
ReceiverInfo ri(r,r2); ReceiverInfo ri(r,r2);
...@@ -616,3 +641,45 @@ UNetExchange* UNetExchange::init_unetexchange( int argc, const char* argv[], Uni ...@@ -616,3 +641,45 @@ UNetExchange* UNetExchange::init_unetexchange( int argc, const char* argv[], Uni
return new UNetExchange(ID,icID,ic); return new UNetExchange(ID,icID,ic);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UNetExchange::receiverEvent( UNetReceiver* r, UNetReceiver::Event ev )
{
// пока, что другие события нас не интересуют
if( ev != UNetReceiver::evTimeout )
return;
for( ReceiverList::iterator it=recvlist.begin(); it!=recvlist.end(); ++it )
{
if( it->r1 == r )
{
// если нет второго канала
// то и переключать некуда
if( !it->r2 )
return;
// пропала связь по первому каналу...
// переключаемся на второй
it->r1->setLockUpdate(true);
it->r2->setLockUpdate(false);
it->r2->resetTimeout();
if( dlog.debugging(Debug::INFO) )
dlog[Debug::INFO] << myname << "(event): " << r->getName()
<< ": timeout for channel1.. select channel2" << endl;
return;
}
if( it->r2 == r )
{
// пропала связь по второму каналу...
// переключаемся на первый
it->r1->setLockUpdate(false);
it->r1->resetTimeout();
it->r2->setLockUpdate(true);
if( dlog.debugging(Debug::INFO) )
dlog[Debug::INFO] << myname << "(event): " << r->getName()
<< ": timeout for channel2.. select channel1" << endl;
return;
}
}
}
// -----------------------------------------------------------------------------
...@@ -106,6 +106,7 @@ class UNetExchange: ...@@ -106,6 +106,7 @@ class UNetExchange:
void timerInfo( UniSetTypes::TimerMessage *tm ); void timerInfo( UniSetTypes::TimerMessage *tm );
void askSensors( UniversalIO::UIOCommand cmd ); void askSensors( UniversalIO::UIOCommand cmd );
void waitSMReady(); void waitSMReady();
void receiverEvent( UNetReceiver* r, UNetReceiver::Event ev );
virtual bool activateObject(); virtual bool activateObject();
...@@ -115,6 +116,7 @@ class UNetExchange: ...@@ -115,6 +116,7 @@ class UNetExchange:
void initIterators(); void initIterators();
void startReceivers(); void startReceivers();
enum Timer enum Timer
{ {
tmStep tmStep
......
...@@ -44,7 +44,7 @@ a_cache_init_ok(false) ...@@ -44,7 +44,7 @@ a_cache_init_ok(false)
{ {
{ {
ostringstream s; ostringstream s;
s << "(" << s_host << ":" << port << ")"; s << "R(" << s_host << ":" << port << ")";
myname = s.str(); myname = s.str();
} }
...@@ -129,6 +129,12 @@ void UNetReceiver::setLostPacketsID( UniSetTypes::ObjectId id ) ...@@ -129,6 +129,12 @@ void UNetReceiver::setLostPacketsID( UniSetTypes::ObjectId id )
shm->initAIterator(aitLostPackets); shm->initAIterator(aitLostPackets);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UNetReceiver::setLockUpdate( bool st )
{
uniset_mutex_lock l(lockMutex,200);
lockUpdate = st;
}
// -----------------------------------------------------------------------------
void UNetReceiver::start() void UNetReceiver::start()
{ {
if( !activated ) if( !activated )
...@@ -265,8 +271,11 @@ void UNetReceiver::real_update() ...@@ -265,8 +271,11 @@ void UNetReceiver::real_update()
} }
// обновление данных в SM (блокировано) // обновление данных в SM (блокировано)
{
uniset_mutex_lock l(lockMutex,100);
if( lockUpdate ) if( lockUpdate )
continue; continue;
}
if( ii.iotype == UniversalIO::DigitalInput ) if( ii.iotype == UniversalIO::DigitalInput )
shm->localSaveState(ii.dit,id,val,shm->ID()); shm->localSaveState(ii.dit,id,val,shm->ID());
...@@ -305,8 +314,11 @@ void UNetReceiver::real_update() ...@@ -305,8 +314,11 @@ void UNetReceiver::real_update()
} }
// обновление данных в SM (блокировано) // обновление данных в SM (блокировано)
{
uniset_mutex_lock l(lockMutex,100);
if( lockUpdate ) if( lockUpdate )
continue; continue;
}
if( ii.iotype == UniversalIO::DigitalInput ) if( ii.iotype == UniversalIO::DigitalInput )
shm->localSaveState(ii.dit,d.id,d.val,shm->ID()); shm->localSaveState(ii.dit,d.id,d.val,shm->ID());
...@@ -364,6 +376,14 @@ void UNetReceiver::receive() ...@@ -364,6 +376,14 @@ void UNetReceiver::receive()
dlog[Debug::WARN] << myname << "(receive): catch ..." << std::endl; dlog[Debug::WARN] << myname << "(receive): catch ..." << std::endl;
} }
if( trTimeout.change(ptRecvTimeout.checkTime()) )
{
if( ptRecvTimeout.checkTime() )
slEvent(this,evTimeout);
else
slEvent(this,evOK);
}
msleep(recvpause); msleep(recvpause);
} }
...@@ -511,3 +531,8 @@ void UNetReceiver::initACache( UniSetUDP::UDPMessage& pack, bool force ) ...@@ -511,3 +531,8 @@ void UNetReceiver::initACache( UniSetUDP::UDPMessage& pack, bool force )
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UNetReceiver::connectEvent( UNetReceiver::EventSlot sl )
{
slEvent = sl;
}
// -----------------------------------------------------------------------------
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <string> #include <string>
#include <queue> #include <queue>
#include <cc++/socket.h> #include <cc++/socket.h>
#include <sigc++/sigc++.h>
#include "UniSetObject_LT.h" #include "UniSetObject_LT.h"
#include "Trigger.h" #include "Trigger.h"
#include "Mutex.h" #include "Mutex.h"
...@@ -58,8 +59,12 @@ class UNetReceiver ...@@ -58,8 +59,12 @@ class UNetReceiver
void receive(); void receive();
void update(); void update();
inline std::string getName(){ return myname; }
// блокировать сохранение данный в SM // блокировать сохранение данный в SM
void setLockUpdate( bool st ){ lockUpdate = st; } void setLockUpdate( bool st );
inline void resetTimeout(){ ptRecvTimeout.reset(); trTimeout.change(false); }
inline bool isRecvOK(){ return ptRecvTimeout.checkTime(); } inline bool isRecvOK(){ return ptRecvTimeout.checkTime(); }
inline unsigned long getLostPacketsNum(){ return lostPackets; } inline unsigned long getLostPacketsNum(){ return lostPackets; }
...@@ -78,6 +83,16 @@ class UNetReceiver ...@@ -78,6 +83,16 @@ class UNetReceiver
inline ost::IPV4Address getAddress(){ return addr; } inline ost::IPV4Address getAddress(){ return addr; }
inline ost::tpport_t getPort(){ return port; } inline ost::tpport_t getPort(){ return port; }
/*! Коды событий */
enum Event
{
evOK, /*!< связь есть */
evTimeout /*!< потеря связи */
};
typedef sigc::slot<void,UNetReceiver*,Event> EventSlot;
void connectEvent( EventSlot sl );
protected: protected:
SMInterface* shm; SMInterface* shm;
...@@ -143,6 +158,10 @@ class UNetReceiver ...@@ -143,6 +158,10 @@ class UNetReceiver
int maxProcessingCount; /*!< максимальное число обрабатываемых за один раз сообщений */ int maxProcessingCount; /*!< максимальное число обрабатываемых за один раз сообщений */
bool lockUpdate; /*!< флаг блокировки сохранения принятых данных в SM */ bool lockUpdate; /*!< флаг блокировки сохранения принятых данных в SM */
UniSetTypes::uniset_mutex lockMutex;
EventSlot slEvent;
Trigger trTimeout;
struct ItemInfo struct ItemInfo
{ {
......
...@@ -23,7 +23,7 @@ s_thr(0) ...@@ -23,7 +23,7 @@ s_thr(0)
{ {
ostringstream s; ostringstream s;
s << "(" << s_host << ":" << port << ")"; s << "S(" << s_host << ":" << port << ")";
myname = s.str(); myname = s.str();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment