diff --git a/copy_firmware_dups.bat b/copy_firmware_dups.bat
index 13d174eae..cf8762634 100644
--- a/copy_firmware_dups.bat
+++ b/copy_firmware_dups.bat
@@ -2,7 +2,20 @@ REM This file is used to make duplicates of critical files for the
REM vscp_firmware repository
copy src\vscp\common\canal.h ..\vscp_firmware\common
+copy src\vscp\common\canal.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
+
copy src\vscp\common\vscp.h ..\vscp_firmware\common
+copy src\vscp\common\vscp.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
+
copy src\vscp\common\vscp_class.h ..\vscp_firmware\common
+copy src\vscp\common\vscp_class.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
+
copy src\vscp\common\vscp_type.h ..\vscp_firmware\common
-copy src\vscp\common\vscp_serial.h ..\vscp_firmware\common
\ No newline at end of file
+copy src\vscp\common\vscp_type.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
+
+copy src\vscp\common\vscp_serial.h ..\vscp_firmware\common
+copy src\vscp\common\vscp_serial.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
+
+copy src\vscp\common\canal_macro.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
+copy src\vscp\common\canaldlldef.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
+copy src\vscp\helperlib\vscphelperlib.h C:\Users\grodansparadis\development\vscp_install_win32\files\include
\ No newline at end of file
diff --git a/src/common/base64-decode.c b/src/common/base64-decode.c
index f37c27a05..febbc94fb 100644
--- a/src/common/base64-decode.c
+++ b/src/common/base64-decode.c
@@ -166,9 +166,9 @@ lws_b64_selftest(void)
for (test = 0; test < sizeof plaintext / sizeof(plaintext[0]); test++) {
buf[sizeof(buf) - 1] = '\0';
- n = lws_b64_encode_string(plaintext[test],
- strlen(plaintext[test]), buf, sizeof buf);
- if (n != strlen(coded[test]) || strcmp(buf, coded[test])) {
+ n = lws_b64_encode_string( plaintext[ test ],
+ strlen( plaintext[test] ), buf, sizeof buf );
+ if ( n != strlen(coded[test] ) || strcmp( buf, coded[test] ) ) {
fprintf(stderr, "Failed lws_b64 encode selftest "
"%d result '%s' %d\n", test, buf, n);
return -1;
diff --git a/src/vscp/common/knownnodes.cpp b/src/vscp/common/knownnodes.cpp
index c67302bf0..a943225b0 100644
--- a/src/vscp/common/knownnodes.cpp
+++ b/src/vscp/common/knownnodes.cpp
@@ -74,6 +74,7 @@
CVSCPServerInformation::CVSCPServerInformation()
{
+ m_bUpdated = false;
m_capabilities = 0;
m_guid.clear();
m_nameOfServer.Empty();
@@ -129,6 +130,7 @@ CVSCPServerInformation::~CVSCPServerInformation()
CNodeInformation::CNodeInformation()
{
+ m_bUpdated = false;
m_bInvestigated = false;
m_realguid.clear();
m_interfaceguid.clear();
diff --git a/src/vscp/common/knownnodes.h b/src/vscp/common/knownnodes.h
index 277776eea..fa2769172 100644
--- a/src/vscp/common/knownnodes.h
+++ b/src/vscp/common/knownnodes.h
@@ -47,6 +47,27 @@ class CVSCPServerInformation
CVSCPServerInformation();
~CVSCPServerInformation();
+ CVSCPServerInformation& operator=( const CVSCPServerInformation& node )
+ {
+ // Check for self-assignment!
+ if ( this == &node ) { // Same object?
+ return *this; // Yes, so skip assignment, and just return *this.
+ }
+
+ m_bUpdated = node.m_bUpdated;
+ m_capabilities = node.m_capabilities;
+ m_guid = node.m_guid;
+ m_nameOfServer = node.m_nameOfServer;
+ m_ipaddress = node.m_ipaddress;
+ memcpy( m_ports, node.m_ports, sizeof( m_ports ) );
+
+ return *this;
+ };
+
+ // This flag can be used by a client to mark this item as seen
+ // by an upfate routine.
+ bool m_bUpdated;
+
// Capabilities for this server
uint64_t m_capabilities;
@@ -98,6 +119,33 @@ class CNodeInformation
CNodeInformation();
~CNodeInformation();
+ CNodeInformation& operator=( const CNodeInformation& node )
+ {
+ // Check for self-assignment!
+ if ( this == &node ) { // Same object?
+ return *this; // Yes, so skip assignment, and just return *this.
+ }
+
+ m_bUpdated = node.m_bUpdated;
+ m_bInvestigated = node.m_bInvestigated;
+ m_bProxy = node.m_bProxy;
+ m_realguid = node.m_realguid;
+ m_interfaceguid = node.m_interfaceguid;
+ m_clientID = node.m_clientID;
+ m_mdfPath = node.m_mdfPath;
+ m_lastHeartBeat = node.m_lastHeartBeat;
+ memcpy( m_stdreg, node.m_stdreg, sizeof( m_stdreg ) );
+ m_strNodeName = node.m_strNodeName;
+ m_deviceName = node.m_deviceName;
+ m_address = node.m_address;
+
+ return *this;
+ };
+
+ // This flag can be used by a client to mark this item as seen
+ // by an upfate routine.
+ bool m_bUpdated;
+
// Thru if this node has been checked
bool m_bInvestigated;
@@ -204,7 +252,6 @@ class CKnownNodes
*/
void load( wxString& path );
-
// Protect the lists
wxMutex m_mutexKnownNodes;
diff --git a/src/vscp/common/version.h b/src/vscp/common/version.h
index 99e15829b..f5c5ba230 100644
--- a/src/vscp/common/version.h
+++ b/src/vscp/common/version.h
@@ -29,9 +29,9 @@
#define VSCPD_SUB_VERSION 0
-#define VSCPD_SUB_SUB_VERSION 2
+#define VSCPD_SUB_SUB_VERSION 4
-#define VSCPD_DISPLAY_VERSION "1.1.0.2 Sodium"
+#define VSCPD_DISPLAY_VERSION "1.1.0.4 Sodium"
#define VSCPD_COPYRIGHT "Copyright (C) 2000-2015, Paradise of the Frog AB, http://www.paradiseofthefrog.com"
#define VSCPD_COPYRIGHT_HTML "Copyright (C) 2000-2015, Paradise of the Frog, http://www.paradiseofthefrog.com"
diff --git a/src/vscp/common/vscp.h b/src/vscp/common/vscp.h
index a4c4e2349..55a747d99 100644
--- a/src/vscp/common/vscp.h
+++ b/src/vscp/common/vscp.h
@@ -372,8 +372,8 @@ typedef VSCPChannelInfo *PVSCPCHANNELINFO;
#define VSCP_MULTICAST_IPV4_ADDRESS_STR "224.0.23.158"
-#define VSCP_MULTICAST_ANNNOUNCE_PORT 9598 //33333
-#define VSCP_MULTICAST_PORT 44444
+#define VSCP_MULTICAST_ANNNOUNCE_PORT 9598
+#define VSCP_MULTICAST_PORT 33333
// Packet format type = 0
#define VSCP_MULTICATS_PACKET0_HEADER_LENGTH 28
diff --git a/src/vscp/common/vscpmulticast.cpp b/src/vscp/common/vscpmulticast.cpp
index 0cc37473c..b0e7bbc27 100644
--- a/src/vscp/common/vscpmulticast.cpp
+++ b/src/vscp/common/vscpmulticast.cpp
@@ -38,6 +38,7 @@
#include
#ifdef WIN32
+
#else
#include
@@ -81,32 +82,20 @@ worksMulticastThread::~worksMulticastThread()
void *worksMulticastThread::Entry()
{
- // Must have a valid pointer to the app. object
- //if ( NULL == m_pApp ) return NULL;
-
crcInit();
//*************************************************************************
// Multicast init.
//*************************************************************************
- int sock; // socket descriptor
- struct sockaddr_in mc_addr; // socket address structure
- unsigned short port = VSCP_MULTICAST_ANNNOUNCE_PORT; // multicast port
- unsigned char ttl = 1; // time to live (hop count)
- int flag_on = 1; // socket option flag
+ int sock; // socket descriptor
+ struct sockaddr_in mc_addr; // socket address structure
+ unsigned short port = VSCP_MULTICAST_ANNNOUNCE_PORT; // multicast port
+ unsigned char ttl = 1; // time to live (hop count)
+ int flag_on = 1; // socket option flag
#ifdef WIN32
- WSADATA wsaData; // Windows socket DLL structure
- struct ip_mreq mc_req; // multicast request structure
-
- // Load Winsock 2.0 DLL
- if ( WSAStartup( MAKEWORD( 2, 0 ), &wsaData ) != 0 ) {
- fprintf( stderr, "Multicast WSAStartup() failed" );
- return NULL;
- }
-
// create a socket for sending to the multicast address
if ( ( sock = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ) {
perror( "Multicast socket() failed" );
@@ -121,11 +110,11 @@ void *worksMulticastThread::Entry()
}
// set the TTL (time to live/hop count) for the send
- if ( ( setsockopt( sock, IPPROTO_IP, IP_MULTICAST_TTL,
+ /*if ( ( setsockopt( sock, IPPROTO_IP, IP_MULTICAST_TTL,
( const char* )&ttl, sizeof( ttl ) ) ) < 0 ) {
perror( "Multicast setsockopt() failed" );
return NULL;
- }
+ }*/
// construct a multicast address structure
memset( &mc_addr, 0, sizeof( mc_addr ) );
@@ -141,6 +130,7 @@ void *worksMulticastThread::Entry()
}
// construct an IGMP join request structure
+ struct ip_mreq mc_req; // multicast request structure
mc_req.imr_multiaddr.s_addr = inet_addr( VSCP_MULTICAST_IPV4_ADDRESS_STR );
mc_req.imr_interface.s_addr = htonl( INADDR_ANY );
@@ -182,7 +172,11 @@ void *worksMulticastThread::Entry()
char buf[ 1024 ]; // buffer to receive string
int recv_len; // length of string received
struct sockaddr_in from_addr; // packet source
+#ifdef WIN32
+ int from_len; // source addr length
+#else
socklen_t from_len; // source addr length
+#endif
int nRcv;
while ( !m_bQuit && !TestDestroy() ) {
@@ -192,7 +186,7 @@ void *worksMulticastThread::Entry()
FD_SET( sock, &fds );
// Set up the struct timeval for the timeout.
- tv.tv_sec = 1;
+ tv.tv_sec = 2;
tv.tv_usec = 0;
// Wait until timeout or data received.
@@ -350,12 +344,12 @@ void *worksMulticastThread::Entry()
// This will use the correct GUID as originator
cguid guid;
- // INterface GUID is used as identifier
+ // Interface GUID is used as identifier
guid.getFromArray( ( unsigned const char * )buf + VSCP_MULTICAST_PACKET0_POS_VSCP_DATA + 32 );
CNodeInformation *pNode = m_knownNodes.addNode( guid );
if ( NULL != pNode ) {
- // not a proxy
+ // Not a proxy
pNode->m_bProxy = true;
// Save the nodes real GUID
@@ -407,11 +401,9 @@ void *worksMulticastThread::Entry()
}
+ }
- }
-
-
- }
+ } // while
#ifdef WIN32
@@ -423,9 +415,6 @@ void *worksMulticastThread::Entry()
// Close the multicast socket
closesocket( sock );
-
- // Cleanup Winsock
- WSACleanup();
#else
close( sock );
#endif
diff --git a/src/vscp/vscpworks/frmmain.cpp b/src/vscp/vscpworks/frmmain.cpp
index a504771d0..b826d110d 100644
--- a/src/vscp/vscpworks/frmmain.cpp
+++ b/src/vscp/vscpworks/frmmain.cpp
@@ -115,12 +115,108 @@ BEGIN_EVENT_TABLE( frmMain, wxFrame )
EVT_IDLE( frmMain::onIdle )
END_EVENT_TABLE()
+
+///////////////////////////////////////////////////////////////////////////////
+// RenderTimer CTor/DTor
+//
+
+RenderTimer::RenderTimer( frmMain *pwnd, worksMulticastThread *pThread ) : wxTimer()
+{
+ m_nLastKnownNodes = 0;
+ m_nLastKnownServers = 0;
+
+ RenderTimer::m_pwnd = pwnd;
+ m_multicastThread = pThread;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Notify
+//
+
+void RenderTimer::Notify()
+{
+ bool bRefresh = false;
+
+ m_multicastThread->m_knownNodes.m_mutexKnownNodes.Lock();
+
+ if ( m_nLastKnownNodes < m_multicastThread->m_knownNodes.m_nodes.size() ) {
+
+ bRefresh = true; // We should update stuff
+
+ VSCP_HASH_KNOWN_NODES::iterator it;
+ for ( it = m_multicastThread->m_knownNodes.m_nodes.begin(); it != m_multicastThread->m_knownNodes.m_nodes.end(); ++it )
+ {
+ wxString key = it->first;
+ CNodeInformation *pNodeInfo = it->second;
+
+ if ( NULL != pNodeInfo ) {
+ nodeClientData *pNode = new nodeClientData( pNodeInfo );
+ if ( NULL != pNode ) {
+ m_pwnd->m_nodeTree->AppendItem( m_pwnd->m_moduleNodeItem, pNodeInfo->m_strNodeName, MDF_EDITOR_SUB_ITEM );
+ }
+ }
+
+ }
+
+
+
+ // Update numbers
+ m_nLastKnownNodes = m_multicastThread->m_knownNodes.m_nodes.size();
+
+ }
+
+ if ( m_nLastKnownServers < m_multicastThread->m_knownNodes.m_servers.size() ) {
+
+ bRefresh = true; // We should update stuff
+
+ VSCP_HASH_KNOWN_SERVERS::iterator it;
+ for ( it = m_multicastThread->m_knownNodes.m_servers.begin(); it != m_multicastThread->m_knownNodes.m_servers.end(); ++it )
+ {
+ wxString key = it->first;
+ CVSCPServerInformation *pNodeInfo = it->second;
+
+ if ( NULL != pNodeInfo ) {
+ serverClientData *pServer = new serverClientData( pNodeInfo );
+ if ( NULL != pServer ) {
+ m_pwnd->m_nodeTree->AppendItem( m_pwnd->m_moduleServerItem, pNodeInfo->m_nameOfServer, MDF_EDITOR_SUB_ITEM );
+ }
+ }
+
+ }
+
+ // Update numbers
+ m_nLastKnownServers = m_multicastThread->m_knownNodes.m_servers.size();
+
+ }
+
+ m_multicastThread->m_knownNodes.m_mutexKnownNodes.Unlock();
+
+ // Refresh the window if necessary
+ if ( bRefresh ) {
+ // Refresh the display
+ m_pwnd->Refresh();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// start
+//
+
+void RenderTimer::start()
+{
+ wxTimer::Start( 5000 );
+}
+
+
+
///////////////////////////////////////////////////////////////////////////////
// frmMain ctor
//
frmMain::frmMain()
{
+ m_timerDiscovery = new RenderTimer( this, wxGetApp().m_pmulticastWorkerThread );
+
Init();
}
@@ -135,7 +231,10 @@ frmMain::frmMain( wxWindow* parent,
const wxSize& size,
long style )
{
- Init();
+ // Create the timer object
+ m_timerDiscovery = new RenderTimer( this, wxGetApp().m_pmulticastWorkerThread );
+
+ Init();
Create( parent, id, caption, pos, size, style );
}
@@ -153,7 +252,7 @@ bool frmMain::Create( wxWindow* parent,
wxFrame::Create( parent, id, caption, pos, size, style );
CreateControls();
- SetIcon(GetIconResource(wxT("../../../docs/vscp/logo/fatbee_v2.ico")));
+ SetIcon( GetIconResource( wxT("../../../docs/vscp/logo/fatbee_v2.ico") ) );
return true;
}
@@ -163,7 +262,7 @@ bool frmMain::Create( wxWindow* parent,
frmMain::~frmMain()
{
-
+ delete m_timerDiscovery;
}
///////////////////////////////////////////////////////////////////////////////
@@ -178,7 +277,7 @@ void frmMain::Init()
}
}
-
+ m_timerDiscovery->Start();
}
@@ -322,18 +421,18 @@ void frmMain::CreateControls()
itemStaticTextTop->SetFont( wxFont( 10, wxSWISS, wxNORMAL, wxBOLD, false, wxT( "Tahoma" ) ) );
itemSizerVertical->Add( itemStaticTextTop, 0, wxALIGN_LEFT | wxALL, 5 );
- m_mdfTree = new wxTreeCtrl;
- m_mdfTree->Create( itemPanel, ID_TREECTRL, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_FULL_ROW_HIGHLIGHT | wxTR_LINES_AT_ROOT | wxTR_ROW_LINES | wxTR_SINGLE );
- itemSizerVertical->Add( m_mdfTree, 10, wxGROW | wxALL, 2 );
+ m_nodeTree = new wxTreeCtrl;
+ m_nodeTree->Create( itemPanel, ID_TREECTRL, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_FULL_ROW_HIGHLIGHT | wxTR_LINES_AT_ROOT | wxTR_ROW_LINES | wxTR_SINGLE );
+ itemSizerVertical->Add( m_nodeTree, 10, wxGROW | wxALL, 2 );
m_htmlInfoWnd = new wxHtmlWindow;
m_htmlInfoWnd->Create( itemPanel, ID_HTMLWINDOW2, wxDefaultPosition, wxSize( -1, 150 ), wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER | wxHSCROLL | wxVSCROLL );
- m_htmlInfoWnd->SetPage( _( "No data
" ) );
+ m_htmlInfoWnd->SetPage( _( "Node information
This area will contain extended information about known (discovered) nodes. This is work in progress sp information is static at the moment." ) );
itemSizerVertical->Add( m_htmlInfoWnd, 0, wxGROW | wxALL, 5 );
// Connect events and objects
- m_mdfTree->Connect( ID_TREECTRL, wxEVT_LEFT_DOWN, wxMouseEventHandler( frmMDFEditor::OnLeftDown ), NULL, this );
- m_mdfTree->Connect( ID_TREECTRL, wxEVT_LEFT_DCLICK, wxMouseEventHandler( frmMDFEditor::OnLeftDClick ), NULL, this );
+ m_nodeTree->Connect( ID_TREECTRL, wxEVT_LEFT_DOWN, wxMouseEventHandler( frmMDFEditor::OnLeftDown ), NULL, this );
+ m_nodeTree->Connect( ID_TREECTRL, wxEVT_LEFT_DCLICK, wxMouseEventHandler( frmMDFEditor::OnLeftDClick ), NULL, this );
wxImageList* itemImageList = new wxImageList( 16, 16, true, 5 );
{
@@ -349,7 +448,7 @@ void frmMain::CreateControls()
itemImageList->Add( Icon4 );
}
- m_mdfTree->AssignImageList( itemImageList );
+ m_nodeTree->AssignImageList( itemImageList );
addDefaultContent();
@@ -426,7 +525,7 @@ wxIcon frmMain::GetIconResource( const wxString& name )
void frmMain::OnCloseWindow( wxCloseEvent& event )
{
-
+ m_timerDiscovery->Stop();
// Save frame size and position
wxRect rc = GetRect();
@@ -500,21 +599,19 @@ void frmMain::OnLeftDClick( wxMouseEvent& event )
void frmMain::addDefaultContent( void )
{
- m_rootItem = m_mdfTree->AddRoot( _( "VSCP Network neighbourhood" ), MDF_EDITOR_TOP_ITEM );
- m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "Daemon TCP/IP Interfaces" ), MDF_EDITOR_MAIN_ITEM );
- m_mdfTree->AppendItem( m_moduleItem, _( "Node" ), MDF_EDITOR_SUB_ITEM );
-
- m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "WEB interface" ), MDF_EDITOR_MAIN_ITEM );
-
- m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "Level II node" ), MDF_EDITOR_MAIN_ITEM );
-
- m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "Websocket interface" ), MDF_EDITOR_MAIN_ITEM );
-
- m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "REST interface" ), MDF_EDITOR_MAIN_ITEM );
-
- m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "MQTT interface" ), MDF_EDITOR_MAIN_ITEM );
-
- m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "CoAP interface" ), MDF_EDITOR_MAIN_ITEM );
+ m_rootItem = m_nodeTree->AddRoot( _( "VSCP Network neighbourhood" ), MDF_EDITOR_TOP_ITEM );
+ m_moduleServerItem = m_nodeTree->AppendItem( m_rootItem, _( "High end nodes" ), MDF_EDITOR_MAIN_ITEM );
+ m_nodeTree->AppendItem( m_moduleServerItem, _( "Node" ), MDF_EDITOR_SUB_ITEM );
+
+ m_moduleNodeItem = m_nodeTree->AppendItem( m_rootItem, _( "Known nodes" ), MDF_EDITOR_MAIN_ITEM );
+ m_nodeTree->AppendItem( m_moduleNodeItem, _( "Node" ), MDF_EDITOR_SUB_ITEM );
+
+ //m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "WEB interface" ), MDF_EDITOR_MAIN_ITEM );
+ //m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "Level II node" ), MDF_EDITOR_MAIN_ITEM );
+ //m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "Websocket interface" ), MDF_EDITOR_MAIN_ITEM );
+ //m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "REST interface" ), MDF_EDITOR_MAIN_ITEM );
+ //m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "MQTT interface" ), MDF_EDITOR_MAIN_ITEM );
+ //m_moduleItem = m_mdfTree->AppendItem( m_rootItem, _( "CoAP interface" ), MDF_EDITOR_MAIN_ITEM );
/*
m_mdfTree->AppendItem( m_moduleItem, _( "Model" ), MDF_EDITOR_SUB_ITEM );
diff --git a/src/vscp/vscpworks/frmmain.h b/src/vscp/vscpworks/frmmain.h
index 6d4bb2983..531f74566 100644
--- a/src/vscp/vscpworks/frmmain.h
+++ b/src/vscp/vscpworks/frmmain.h
@@ -56,9 +56,10 @@
#include "wx/toolbar.h"
#include "wx/treectrl.h"
#include "wx/html/htmlwin.h"
+#include
#include
-
+#include
// Control identifiers
#define SYMBOL_FRMMAIN_STYLE wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX
@@ -73,8 +74,80 @@
#define wxCLOSE_BOX 0x1000
#endif
+// Forward declarations
+class frmMain;
+
+///////////////////////////////////////////////////////////////////////////////
+// serverClientData
+//
+
+class serverClientData : public wxTreeItemData
+{
+
+public:
+
+ serverClientData( CVSCPServerInformation* psrv )
+ : wxTreeItemData()
+ {
+ m_serverInformation = *psrv;
+ };
+
+ CVSCPServerInformation m_serverInformation;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// nodeClientData
+//
+
+class nodeClientData : public wxTreeItemData
+{
+
+public:
+
+ nodeClientData( CNodeInformation* pnode )
+ : wxTreeItemData()
+ {
+ m_nodeInformation = *pnode;
+ };
+
+public:
+
+ CNodeInformation m_nodeInformation;
+};
+
+//YourTreeClientData *d = new YourTreeClientData();
+//d->SetRefClass( YourClass );
+
+//m_treeCtrl->AppendItem( parent_id, wxT( "Hello" ), -1, -1, d );
+
+///////////////////////////////////////////////////////////////////////////////
+// RenderTimer
+//
+
+class RenderTimer : public wxTimer
+{
+public:
+ RenderTimer( frmMain *pwnd, worksMulticastThread *pThread );
+
+ void Notify();
+ void start();
+
+ // Last number of known nodes if this differs with current
+ // number interface data should be updated
+ uint16_t m_nLastKnownNodes;
+
+ // Last number of known servers if this differs with current
+ // number interface data should be updated
+ uint16_t m_nLastKnownServers;
+ frmMain* m_pwnd; // Main window
+
+ // The multicast thread
+ // The threadobject holds information about discovered nodes
+ // !!!! MUST BE protected by wxGetApp().m_mutexmulticastWorkerThread !!!!
+ worksMulticastThread* m_multicastThread;
+};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -204,8 +277,13 @@ class frmMain: public wxFrame
wxTreeItemId m_rootItem;
/// Module item of the list
- wxTreeItemId m_moduleItem;
+ wxTreeItemId m_moduleServerItem;
+
+ /// Module item of the list
+ wxTreeItemId m_moduleNodeItem;
+ /// Timer for discovery updates
+ RenderTimer* m_timerDiscovery;
/// Control identifiers
enum {
@@ -242,7 +320,7 @@ class frmMain: public wxFrame
*/
wxStaticBitmap* m_pStaticBitmapLogo;
wxStatusBar* m_pitemStatusBar;
- wxTreeCtrl* m_mdfTree;
+ wxTreeCtrl* m_nodeTree;
wxHtmlWindow* m_htmlInfoWnd;
};
diff --git a/src/vscp/vscpworks/vscpworks.cpp b/src/vscp/vscpworks/vscpworks.cpp
index ad5b0a9dc..b3a5b8d7b 100644
--- a/src/vscp/vscpworks/vscpworks.cpp
+++ b/src/vscp/vscpworks/vscpworks.cpp
@@ -113,7 +113,7 @@ WX_DEFINE_LIST(LIST_VSCP_IF);
* Application instance implementation
*/
-IMPLEMENT_APP( VscpworksApp )
+IMPLEMENT_APP( VscpworksApp )
/*!
@@ -149,7 +149,14 @@ VscpworksApp::VscpworksApp()
// net_skeleton generates on no receiving socket at other end
// we can safely dismiss.
-#ifndef WIN32
+#ifdef WIN32
+ WSADATA wsaData; // Windows socket DLL structure
+
+ // Load Winsock 2.0 DLL
+ if ( WSAStartup( MAKEWORD( 2, 0 ), &wsaData ) != 0 ) {
+ fprintf( stderr, "Multicast WSAStartup() failed" );
+ }
+#else
//int set = 1;
//setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
signal(SIGPIPE, SIG_IGN);
@@ -418,6 +425,11 @@ int VscpworksApp::OnExit()
m_mutexmulticastWorkerThread.Unlock();
}
+#ifdef WIN32
+ // Cleanup Winsock
+ WSACleanup();
+#endif
+
//_CrtDumpMemoryLeaks();
return wxApp::OnExit();