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();