diff --git a/dashboard/changes.txt b/dashboard/changes.txt index d20e112..71db549 100755 --- a/dashboard/changes.txt +++ b/dashboard/changes.txt @@ -1,3 +1,12 @@ +xlx db v2.3.4 + +add filter function to the dashboard. It can be enabled or disabled via the config.inc.php + +- "index.php" +- "users.php" +- "config.inc.php" $PageOptions['UserPage']['ShowFilter'] added +- "layout.css" + xlx db v2.3.3 now displays always the correct module for the last heard station. diff --git a/dashboard/css/layout.css b/dashboard/css/layout.css index 50ffc80..1e73eb0 100755 --- a/dashboard/css/layout.css +++ b/dashboard/css/layout.css @@ -107,4 +107,28 @@ background-image: linear-gradient(to bottom, rgb(201, 231, 233) 0%, rgb(220, 237 width : 90%; padding : 15px; margin : 5px; +} + +.FilterField { + font-size : 10pt; + text-decoration : none, + color : #000000; + background-color : #FFFFFF; + width : 150px; + height : 20px; + padding-left : 5px; + padding-top : 3px; + border : 1px #60A1DE solid; +} + +.FilterSubmit { + font-size : 10pt; + text-decoration : none, + color : #000000; + background-color : #FFFFFF; + height : 26px; + width : 60px; + padding-left : 5px; + padding-top : 3px; + border : 1px #60A1DE solid; } \ No newline at end of file diff --git a/dashboard/img/flags/hk.png b/dashboard/img/flags/hk.png old mode 100644 new mode 100755 diff --git a/dashboard/img/tx.gif b/dashboard/img/tx.gif old mode 100644 new mode 100755 diff --git a/dashboard/index.php b/dashboard/index.php index 74d0b5d..93e02f8 100755 --- a/dashboard/index.php +++ b/dashboard/index.php @@ -1,5 +1,7 @@ 4) { - if ($LastSync < (time() - $CallingHome['PushDelay'])) { - $Ressource = @fopen($CallingHome['HashFile'],"w"); - if ($Ressource) { - @fwrite($Ressource, "'); - @fclose($Ressource); - } - $CallHomeNow = true; - } - } + include($CallingHome['HashFile']); + if ($LastSync < (time() - $CallingHome['PushDelay'])) { + $Ressource = @fopen($CallingHome['HashFile'],"w"); + if ($Ressource) { + @fwrite($Ressource, "'); + @fclose($Ressource); } + $CallHomeNow = true; } } @@ -100,7 +96,7 @@ else { if (!isset($_GET['show']) || (($_GET['show'] != 'liveircddb') && ($_GET['show'] != 'reflectors') && ($_GET['show'] != 'interlinks'))) { echo ' - setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');'; + setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');'; } echo ' diff --git a/dashboard/pgs/config.inc.php b/dashboard/pgs/config.inc.php index d017795..86031b9 100755 --- a/dashboard/pgs/config.inc.php +++ b/dashboard/pgs/config.inc.php @@ -16,7 +16,7 @@ $PageOptions = array(); $PageOptions['ContactEmail'] = 'your_email'; // Support E-Mail address -$PageOptions['DashboardVersion'] = '2.3.3'; // Dashboard Version +$PageOptions['DashboardVersion'] = '2.3.4'; // Dashboard Version $PageOptions['PageRefreshActive'] = true; // Activate automatic refresh $PageOptions['PageRefreshDelay'] = '10000'; // Page refresh time in miliseconds @@ -47,7 +47,7 @@ $PageOptions['MetaAuthor'] = 'LX1IQ'; $PageOptions['MetaRevisit'] = 'After 30 Days'; // Meta Tag Values, usefull for Search Engine $PageOptions['MetaRobots'] = 'index,follow'; // Meta Tag Values, usefull for Search Engine - +$PageOptions['UserPage']['ShowFilter'] = true; // Show Filter on Users page $Service['PIDFile'] = '/var/log/xlxd.pid'; $Service['XMLFile'] = '/var/log/xlxd.xml'; diff --git a/dashboard/pgs/country.csv b/dashboard/pgs/country.csv index a07ab6d..2787544 100755 --- a/dashboard/pgs/country.csv +++ b/dashboard/pgs/country.csv @@ -162,7 +162,7 @@ Niger;NE;5U Nigeria;NG;5N Niue;NU;ZK2 Norfolk Island;NF;VK9N -Northern Ireland;NIE;GI-MI +Northern Ireland;NIE;2I-GI-MI Northern Mariana Islands;MP;KH0 Norway;NO;LA-LB-LC-LD-LE-LF-LG-LH-LI-LJ-LK-LL-LM-LN Oman;OM;YP-YQ-YR @@ -234,7 +234,7 @@ Tuvalu;TV;T2 Uganda;UG;5X Ukraine;UA;UR-US-UT-UU-UV-UW-UX-UY-UZ United Arab Emirates;AE;A6 -United Kingdom;GB;2E-M0-M1-M2-M3-M4-M5-M6-M7-M8-M9-MB-MM-G0-G1-G2-G3-G4-G5-G6-G7-G8-G9-GX +United Kingdom;GB;2E-M0-M1-M2-M3-M4-M5-M6-M7-M8-M9-MB-MM-G0-G1-G2-G3-G4-G5-G6-G7-G8-G9-GB-GO-GQ-GR-GX United States;US;K0-K1-K2-K3-K4-K5-K6-K7-K8-K9-KA-KB-KC-KD-KE-KF-KG-KH-KI-KJ-KK-KM-KN-KO-KQ-KR-KS-KT-KU-KV-KW-KX-KY-KZ-W0-W1-W2-W3-W4-W5-W6-W7-W8-W9-WA-WB-WD-WF-WR-WV-WX-WZ-N0-N1-N2-N3-N4-N5-N6-N7-N8-N9-NA-NB-NE-NG-NN-NO-NQ-NS-NU-NW-AA-AB-AC-AD-AE-AF-AG-AH-AI-AJ-AK United States Minor Outlying Islands;UM; Uruguay;UY;CV-CW-CX diff --git a/dashboard/pgs/users.php b/dashboard/pgs/users.php index 2de0a10..58865ca 100755 --- a/dashboard/pgs/users.php +++ b/dashboard/pgs/users.php @@ -1,9 +1,78 @@ +
- +
+ +'; +} + + +?> @@ -13,42 +82,62 @@ - -LoadFlags(); $odd = ""; for ($i=0;$i<$Reflector->StationCount();$i++) { - if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; } - echo ' + $ShowThisStation = true; + if ($PageOptions['UserPage']['ShowFilter']) { + $CS = true; + if ($_SESSION['FilterCallSign'] != null) { + if (!fnmatch($_SESSION['FilterCallSign'], $Reflector->Stations[$i]->GetCallSign(), FNM_CASEFOLD)) { + $CS = false; + } + } + $MO = true; + if ($_SESSION['FilterModule'] != null) { + if (trim(strtolower($_SESSION['FilterModule'])) != strtolower($Reflector->Stations[$i]->GetModule())) { + $MO = false; + } + } + + $ShowThisStation = ($CS && $MO); + } + + + if ($ShowThisStation) { + if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; } + echo ' + echo ' + if (file_exists("./img/flags/".$Reflector->GetFlag($Reflector->Stations[$i]->GetCallSign()).".png")) { + echo ''; + } + echo ' + if ($Reflector->Stations[$i]->GetPeer() != $Reflector->GetReflectorName()) { + echo ' / '.$Reflector->Stations[$i]->GetPeer(); + } + echo ''; + } if ($i == 39) { $i = $Reflector->StationCount()+1; } } diff --git a/src/cdcsprotocol.cpp b/src/cdcsprotocol.cpp index 48a0c52..2a0b9f8 100644 --- a/src/cdcsprotocol.cpp +++ b/src/cdcsprotocol.cpp @@ -99,12 +99,12 @@ void CDcsProtocol::Task(void) if ( !Frame->IsLastPacket() ) { //std::cout << "DCS DV frame" << std::endl; - OnDvFramePacketIn(Frame); + OnDvFramePacketIn(Frame, &Ip); } else { //std::cout << "DCS DV last frame" << std::endl; - OnDvLastFramePacketIn((CDvLastFramePacket *)Frame); + OnDvLastFramePacketIn((CDvLastFramePacket *)Frame, &Ip); } } else @@ -245,6 +245,12 @@ bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) // update last heard g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.ReleaseUsers(); + + // delete header if needed + if ( !newstream ) + { + delete Header; + } } else { diff --git a/src/cdextraprotocol.cpp b/src/cdextraprotocol.cpp index 5c33331..8aa88ab 100644 --- a/src/cdextraprotocol.cpp +++ b/src/cdextraprotocol.cpp @@ -80,7 +80,7 @@ void CDextraProtocol::Task(void) //std::cout << "DExtra DV frame" << std::endl; // handle it - OnDvFramePacketIn(Frame); + OnDvFramePacketIn(Frame, &Ip); } else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL ) { @@ -103,7 +103,7 @@ void CDextraProtocol::Task(void) //std::cout << "DExtra DV last frame" << std::endl; // handle it - OnDvLastFramePacketIn(LastFrame); + OnDvLastFramePacketIn(LastFrame, &Ip); } else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule, &ProtRev) ) { @@ -331,6 +331,12 @@ bool CDextraProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) // update last heard g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.ReleaseUsers(); + + // delete header if needed + if ( !newstream ) + { + delete Header; + } } else { diff --git a/src/cdplusprotocol.cpp b/src/cdplusprotocol.cpp index a5c68ec..37cfbca 100644 --- a/src/cdplusprotocol.cpp +++ b/src/cdplusprotocol.cpp @@ -92,7 +92,7 @@ void CDplusProtocol::Task(void) //std::cout << "DPlus DV frame" << std::endl; // handle it - OnDvFramePacketIn(Frame); + OnDvFramePacketIn(Frame, &Ip); } else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL ) { @@ -114,7 +114,7 @@ void CDplusProtocol::Task(void) //std::cout << "DPlus DV last frame" << std::endl; // handle it - OnDvLastFramePacketIn(LastFrame); + OnDvLastFramePacketIn(LastFrame, &Ip); } else if ( IsValidConnectPacket(Buffer) ) { @@ -250,6 +250,12 @@ bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) // update last heard g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.ReleaseUsers(); + + // delete header if needed + if ( !newstream ) + { + delete Header; + } } else { diff --git a/src/cpacketstream.cpp b/src/cpacketstream.cpp index 5e78bee..0ad2a64 100644 --- a/src/cpacketstream.cpp +++ b/src/cpacketstream.cpp @@ -73,3 +73,15 @@ void CPacketStream::Push(CPacket *Packet) push(Packet); } +//////////////////////////////////////////////////////////////////////////////////////// +// get + +const CIp *CPacketStream::GetOwnerIp(void) +{ + if ( m_OwnerClient != NULL ) + { + return &(m_OwnerClient->GetIp()); + } + return NULL; +} + diff --git a/src/cpacketstream.h b/src/cpacketstream.h index 2c5575c..a60a4bc 100644 --- a/src/cpacketstream.h +++ b/src/cpacketstream.h @@ -55,7 +55,9 @@ public: // get CClient *GetOwnerClient(void) { return m_OwnerClient; } + const CIp *GetOwnerIp(void); bool IsExpired(void) const { return (m_LastPacketTime.DurationSinceNow() > STREAM_TIMEOUT); } + bool IsOpen(void) const { return m_bOpen; } uint16 GetStreamId(void) const { return m_uiStreamId; } const CCallsign &GetUserCallsign(void) const { return m_DvHeader.GetMyCallsign(); } diff --git a/src/cprotocol.cpp b/src/cprotocol.cpp index 6922d68..2cb3b58 100644 --- a/src/cprotocol.cpp +++ b/src/cprotocol.cpp @@ -134,10 +134,10 @@ bool CProtocol::EncodeDvPacket(const CPacket &packet, CBuffer *buffer) const //////////////////////////////////////////////////////////////////////////////////////// // streams helpers -void CProtocol::OnDvFramePacketIn(CDvFramePacket *Frame) +void CProtocol::OnDvFramePacketIn(CDvFramePacket *Frame, const CIp *Ip) { // find the stream - CPacketStream *stream = GetStream(Frame->GetStreamId()); + CPacketStream *stream = GetStream(Frame->GetStreamId(), Ip); if ( stream != NULL ) { //std::cout << "DV frame" << std::endl; @@ -148,10 +148,10 @@ void CProtocol::OnDvFramePacketIn(CDvFramePacket *Frame) } } -void CProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *Frame) +void CProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *Frame, const CIp *Ip) { // find the stream - CPacketStream *stream = GetStream(Frame->GetStreamId()); + CPacketStream *stream = GetStream(Frame->GetStreamId(), Ip); if ( stream != NULL ) { // push @@ -167,16 +167,23 @@ void CProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *Frame) //////////////////////////////////////////////////////////////////////////////////////// // stream handle helpers -CPacketStream *CProtocol::GetStream(uint16 uiStreamId) +CPacketStream *CProtocol::GetStream(uint16 uiStreamId, const CIp *Ip) { CPacketStream *stream = NULL; + + // find if we have a stream with same streamid in our cache for ( int i = 0; (i < m_Streams.size()) && (stream == NULL); i++ ) { if ( m_Streams[i]->GetStreamId() == uiStreamId ) { - stream = m_Streams[i]; + // if Ip not NULL, also check if IP match + if ( (Ip != NULL) && (*Ip == *(m_Streams[i]->GetOwnerIp())) ) + { + stream = m_Streams[i]; + } } } + // done return stream; } diff --git a/src/cprotocol.h b/src/cprotocol.h index f176e57..265bec8 100644 --- a/src/cprotocol.h +++ b/src/cprotocol.h @@ -70,11 +70,11 @@ protected: // stream helpers virtual bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &) { return false; } - virtual void OnDvFramePacketIn(CDvFramePacket *); - virtual void OnDvLastFramePacketIn(CDvLastFramePacket *); + virtual void OnDvFramePacketIn(CDvFramePacket *, const CIp * = NULL); + virtual void OnDvLastFramePacketIn(CDvLastFramePacket *, const CIp * = NULL); // stream handle helpers - CPacketStream *GetStream(uint16); + CPacketStream *GetStream(uint16, const CIp * = NULL); void CheckStreamsTimeout(void); // queue helper diff --git a/src/creflector.cpp b/src/creflector.cpp index 2ec17b4..dd9e32c 100644 --- a/src/creflector.cpp +++ b/src/creflector.cpp @@ -176,37 +176,48 @@ CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, CClient *client // check if client is valid candidate if ( m_Clients.IsClient(client) && !client->IsAMaster() ) { - // get the module's queue - char module = DvHeader->GetRpt2Module(); - CPacketStream *stream = GetStream(module); - if ( stream != NULL ) + // check if no stream with same streamid already open + // to prevent loops + if ( !IsStreamOpen(DvHeader) ) { - // lock it - stream->Lock(); - // is it available ? - if ( stream->Open(*DvHeader, client) ) + // get the module's queue + char module = DvHeader->GetRpt2Module(); + CPacketStream *stream = GetStream(module); + if ( stream != NULL ) { - // stream open, mark client as master - // so that it can't be deleted - client->SetMasterOfModule(module); + // lock it + stream->Lock(); + // is it available ? + if ( stream->Open(*DvHeader, client) ) + { + // stream open, mark client as master + // so that it can't be deleted + client->SetMasterOfModule(module); - // update last heard time - client->Heard(); - retStream = stream; + // update last heard time + client->Heard(); + retStream = stream; - // and push header packet - stream->Push(DvHeader); + // and push header packet + stream->Push(DvHeader); - // report - std::cout << "Opening stream on module " << module << " for client " << client->GetCallsign() - << " with sid " << DvHeader->GetStreamId() << std::endl; + // report + std::cout << "Opening stream on module " << module << " for client " << client->GetCallsign() + << " with sid " << DvHeader->GetStreamId() << std::endl; - // notify - g_Reflector.OnStreamOpen(stream->GetUserCallsign()); + // notify + g_Reflector.OnStreamOpen(stream->GetUserCallsign()); + } + // unlock now + stream->Unlock(); } - // unlock now - stream->Unlock(); + } + else + { + // report + std::cout << "Detected stream loop on module " << DvHeader->GetRpt2Module() << " for client " << client->GetCallsign() + << " with sid " << DvHeader->GetStreamId() << std::endl; } } @@ -525,6 +536,17 @@ CPacketStream *CReflector::GetStream(char module) return stream; } +bool CReflector::IsStreamOpen(const CDvHeaderPacket *DvHeader) +{ + bool open = false; + for ( int i = 0; (i < m_Streams.size()) && !open; i++ ) + { + open = ( (m_Streams[i].GetStreamId() == DvHeader->GetStreamId()) && + (m_Streams[i].IsOpen())); + } + return open; +} + char CReflector::GetStreamModule(CPacketStream *stream) { char module = ' '; diff --git a/src/creflector.h b/src/creflector.h index 07700b9..51cb18d 100644 --- a/src/creflector.h +++ b/src/creflector.h @@ -101,6 +101,7 @@ protected: // streams CPacketStream *GetStream(char); + bool IsStreamOpen(const CDvHeaderPacket *); char GetStreamModule(CPacketStream *); // xml helpers diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp index 4a20988..c6f645a 100644 --- a/src/cxlxprotocol.cpp +++ b/src/cxlxprotocol.cpp @@ -81,7 +81,7 @@ void CXlxProtocol::Task(void) //std::cout << "XLX (DExtra) DV frame" << std::endl; // handle it - OnDvFramePacketIn(Frame); + OnDvFramePacketIn(Frame, &Ip); } else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL ) { @@ -104,7 +104,7 @@ void CXlxProtocol::Task(void) //std::cout << "XLX (DExtra) DV last frame" << std::endl; // handle it - OnDvLastFramePacketIn(LastFrame); + OnDvLastFramePacketIn(LastFrame, &Ip); } else if ( IsValidConnectPacket(Buffer, &Callsign, Modules, &Major, &Minor, &Revision) ) { @@ -415,26 +415,32 @@ bool CXlxProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), Header->GetRpt1Callsign(), Header->GetRpt2Callsign(), peer); g_Reflector.ReleaseUsers(); + // delete header if needed + if ( !newstream ) + { + delete Header; + } + // done return newstream; } -void CXlxProtocol::OnDvFramePacketIn(CDvFramePacket *DvFrame) +void CXlxProtocol::OnDvFramePacketIn(CDvFramePacket *DvFrame, const CIp *Ip) { // tag packet as remote peer origin DvFrame->SetRemotePeerOrigin(); // anc call base class - CDextraProtocol::OnDvFramePacketIn(DvFrame); + CDextraProtocol::OnDvFramePacketIn(DvFrame, Ip); } -void CXlxProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *DvFrame) +void CXlxProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *DvFrame, const CIp *Ip) { // tag packet as remote peer origin DvFrame->SetRemotePeerOrigin(); // anc call base class - CDextraProtocol::OnDvLastFramePacketIn(DvFrame); + CDextraProtocol::OnDvLastFramePacketIn(DvFrame, Ip); } diff --git a/src/cxlxprotocol.h b/src/cxlxprotocol.h index 2a6f7fc..795fa06 100644 --- a/src/cxlxprotocol.h +++ b/src/cxlxprotocol.h @@ -61,8 +61,8 @@ protected: // stream helpers bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &); - void OnDvFramePacketIn(CDvFramePacket *); - void OnDvLastFramePacketIn(CDvLastFramePacket *); + void OnDvFramePacketIn(CDvFramePacket *, const CIp * = NULL); + void OnDvLastFramePacketIn(CDvLastFramePacket *, const CIp * = NULL); // packet decoding helpers bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *); diff --git a/src/main.h b/src/main.h index 8844bbc..eff6f73 100644 --- a/src/main.h +++ b/src/main.h @@ -48,7 +48,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 4 -#define VERSION_REVISION 1 +#define VERSION_REVISION 2 // global ------------------------------------------------------
+ + + + +
+
+ + + +
+
+
+ + + +
+
+
# FlagVia / Peer Last heard Listening on
'; - if ($i==0 && $Reflector->Stations[$i]->GetLastHeardTime() > (time() - 60)) { - echo ''; - } - else { - echo ($i+1); - } + if ($i==0 && $Reflector->Stations[$i]->GetLastHeardTime() > (time() - 60)) { + echo ''; + } + else { + echo ($i+1); + } - echo ' '; - if (file_exists("./img/flags/".$Reflector->GetFlag($Reflector->Stations[$i]->GetCallSign()).".png")) { - echo ''; - } - echo ' '.$Reflector->Stations[$i]->GetCallsignOnly().' '.$Reflector->Stations[$i]->GetSuffix().' '.$Reflector->Stations[$i]->GetVia(); - if ($Reflector->Stations[$i]->GetPeer() != $Reflector->GetReflectorName()) { - echo ' / '.$Reflector->Stations[$i]->GetPeer(); - } - echo ' '.@date("d.m.Y H:i", $Reflector->Stations[$i]->GetLastHeardTime()).' '.$Reflector->Stations[$i]->GetModule().'