void *VSCPMQTTBrokerThread::Entry() { struct mg_mgr mgr; struct mg_connection *nc; struct mg_mqtt_broker brk; const char *address = "0.0.0.0:1883"; // Check pointers if ( NULL == m_pCtrlObject ) return NULL; // We need to create a clientobject and add this object to the list m_pClientItem = new CClientItem; if ( NULL == m_pClientItem ) { m_pCtrlObject->logMsg( _( "[VSCP MQTT Broker] Unable to allocate memory for client.\n" ) ); return NULL; } // This is now an active Client m_pClientItem->m_bOpen = true; m_pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_CLIENT_UDP; m_pClientItem->m_strDeviceName = _("VSCP MQTT Broker: Started at "); wxDateTime now = wxDateTime::Now(); m_pClientItem->m_strDeviceName += now.FormatISODate(); m_pClientItem->m_strDeviceName += _(" "); m_pClientItem->m_strDeviceName += now.FormatISOTime(); // Add the client to the Client List m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->addClient( m_pClientItem ); m_pCtrlObject->m_wxClientMutex.Unlock(); // Clear the filter (Allow everything ) vscp_clearVSCPFilter( &m_pClientItem->m_filterVSCP ); mg_mgr_init( &mgr, this ); mg_mqtt_broker_init( &brk, NULL ); if ( ( nc = mg_bind( &mgr, m_pCtrlObject->m_strMQTTBrokerInterfaceAddress.mbc_str(), mg_mqtt_broker ) ) == NULL) { m_pCtrlObject->logMsg( _("VSCP MQTT Broker: Faild to bind to requested address.\n") ); return NULL; } nc->user_data = &brk; m_pCtrlObject->logMsg( _("VSCP MQTT Broker: Thread started.\n") ); while ( !TestDestroy() && !m_bQuit ) { mg_mgr_poll( &mgr, 1000 ); } // release the server //ns_mgr_free( &m_pCtrlObject->m_mgrTcpIpServer ); mg_mgr_free( &mgr ); m_pCtrlObject->logMsg( _( "VSCP MQTT Broker: Quit.\n" ) ); return NULL; }
Csocketcan::Csocketcan() { m_bQuit = false; m_pthreadWorker = NULL; m_interface = _("vcan0"); vscp_clearVSCPFilter(&m_vscpfilter); // Accept all events ::wxInitialize(); }
CUserItem::CUserItem(void) { m_userID = VSCP_ADD_USER_UNINITIALISED; // Accept all events vscp_clearVSCPFilter( &m_filterVSCP ); // No user rights memset( m_userRights, 0, sizeof( m_userRights ) ); }
Csocketcan::Csocketcan() { m_bQuit = false; m_interface = "vcan0"; vscp_clearVSCPFilter(&m_vscpfilter); // Accept all events sem_init(&m_semSendQueue, 0, 0); sem_init(&m_semReceiveQueue, 0, 0); pthread_mutex_init(&m_mutexSendQueue, NULL); pthread_mutex_init(&m_mutexReceiveQueue, NULL); }
Cmqttobj::Cmqttobj() { m_bQuit = false; m_bConnected = false; m_pthreadWork = NULL; m_bSubscribe = true; m_bSimplify = false; m_simple_class = 0; m_simple_type = 0; m_simple_coding = 0; m_simple_zone = 0; m_simple_subzone = 0; m_topic_list[0].qos = 0; m_topic_list[ 0 ].topic = NULL, vscp_clearVSCPFilter(&m_vscpfilter); // Accept all events ::wxInitialize(); }
void dlgVscpInterfaceSettings::Init() { ////@begin dlgVscpInterfaceSettings member initialisation m_panelCanal = NULL; m_DriverDescription = NULL; m_PathToDriver = NULL; m_DriverConfigurationString = NULL; m_DriverFlags = NULL; m_panelServer = NULL; m_RemoteServerDescription = NULL; m_RemoteServerURL = NULL; m_RemoteServerUsername = NULL; m_RemoteServerPassword = NULL; m_fullLevel2 = NULL; m_RemoteInterfaceName = NULL; m_btnTestConnection = NULL; m_btnGetInterfaces = NULL; ////@end dlgVscpInterfaceSettings member initialisation // Init filter vscp_clearVSCPFilter( &m_vscpfilter ); }
CClientItem::CClientItem() { m_bOpen = false; // Initially Not Open m_flags = 0; // No flags m_status.channel_status = 0; m_clientID = 0; m_type = CLIENT_ITEM_INTERFACE_TYPE_NONE; m_bUDPReceiveChannel = false; // Nill GUID m_guid.clear(); // Nill Level II mask (accept all) vscp_clearVSCPFilter( &m_filterVSCP ); m_statistics.cntReceiveFrames = 0; // # of receive frames m_statistics.cntTransmitFrames = 0; // # of transmitted frames m_statistics.cntReceiveData = 0; // # of received data bytes m_statistics.cntTransmitData = 0; // # of transmitted data bytes m_statistics.cntOverruns = 0; // # of overruns m_statistics.cntBusWarnings = 0; // # of bys warnings m_statistics.cntBusOff = 0; // # of bus off's m_status.channel_status = 0; m_status.lasterrorcode = 0; m_status.lasterrorsubcode = 0; memset( m_status.lasterrorstr, 0, sizeof( m_status.lasterrorstr ) ); /////////////////////////////////////////////////////////////////////////// // Working variable storage for clients ////////////////////////////////////////////////////////////////////////// bAuthenticated = false; m_pUserItem = NULL; /// Buffer for read data wxString m_readBuffer; }
CRawEthernet::CRawEthernet() { m_bQuit = false; m_preadWorkThread = NULL; m_pwriteWorkThread = NULL; m_interface = _("eth0"); memset(m_localMac, 0, 16); // Initialize tx channel GUID m_localGUIDtx.clear(); m_localGUIDtx.setAt(0, 0xff); m_localGUIDtx.setAt(1, 0xff); m_localGUIDtx.setAt(2, 0xff); m_localGUIDtx.setAt(3, 0xff); m_localGUIDtx.setAt(4, 0xff); m_localGUIDtx.setAt(5, 0xff); m_localGUIDtx.setAt(6, 0xff); m_localGUIDtx.setAt(7, 0xfe); m_localGUIDtx.setAt(14, 0x00); m_localGUIDtx.setAt(15, 0x00); // Initialize rx channel GUID m_localGUIDrx.clear(); m_localGUIDrx.setAt(0, 0xff); m_localGUIDrx.setAt(1, 0xff); m_localGUIDrx.setAt(2, 0xff); m_localGUIDrx.setAt(3, 0xff); m_localGUIDrx.setAt(4, 0xff); m_localGUIDrx.setAt(5, 0xff); m_localGUIDrx.setAt(6, 0xff); m_localGUIDrx.setAt(7, 0xfe); m_localGUIDrx.setAt(14, 0x00); m_localGUIDrx.setAt(15, 0x01); vscp_clearVSCPFilter(&m_vscpfilter); // Accept all events ::wxInitialize(); }
void *daemonVSCPThread::Entry() { int sock_mc; // socket descriptor struct sockaddr_in mc_addr; // socket address structure unsigned short mc_port = vscp_readStringValue( m_pCtrlObject->m_strMulticastAnnounceAddress ) ; // multicast port unsigned char mc_ttl = m_pCtrlObject->m_ttlMultiCastAnnounce; // time to live (hop count) #ifdef WIN32 WSADATA wsaData; // Windows socket DLL structure // Load Winsock 2.0 DLL if ( WSAStartup( MAKEWORD( 2, 0 ), &wsaData ) != 0 ) { fprintf( stderr, "WSAStartup() failed" ); m_pCtrlObject->logMsg( _( "Automation multicast announce WSAStartup() failed\n" ), DAEMON_LOGMSG_NORMAL, DAEMON_LOGTYPE_GENERAL ); return NULL; } // create a socket for sending to the multicast address if ( ( sock_mc = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ) { perror( "socket() failed" ); m_pCtrlObject->logMsg( _( "Automation multicast announce sock() failed\n" ), DAEMON_LOGMSG_NORMAL, DAEMON_LOGTYPE_GENERAL ); return NULL; } // set the TTL (time to live/hop count) for the send if ( ( setsockopt( sock_mc, IPPROTO_IP, IP_MULTICAST_TTL, ( const char* )&mc_ttl, sizeof( mc_ttl ) ) ) < 0 ) { perror( "setsockopt() failed" ); m_pCtrlObject->logMsg( _( "Automation multicast announce setsockopt() failed\n" ), DAEMON_LOGMSG_NORMAL, DAEMON_LOGTYPE_GENERAL ); return NULL; } // construct a multicast address structure memset( &mc_addr, 0, sizeof( mc_addr ) ); mc_addr.sin_family = AF_INET; mc_addr.sin_addr.s_addr = inet_addr( VSCP_MULTICAST_IPV4_ADDRESS_STR ); mc_addr.sin_port = htons( mc_port ); #else // create a socket for sending to the multicast address if ( ( sock_mc = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ) { perror( "socket() failed" ); return NULL; } // set the TTL (time to live/hop count) for the send if ( ( setsockopt( sock_mc, IPPROTO_IP, IP_MULTICAST_TTL, ( void* )&mc_ttl, sizeof( mc_ttl ) ) ) < 0 ) { perror( "setsockopt() failed" ); return NULL; } // construct a multicast address structure memset( &mc_addr, 0, sizeof( mc_addr ) ); mc_addr.sin_family = AF_INET; mc_addr.sin_addr.s_addr = inet_addr( VSCP_MULTICAST_IPV4_ADDRESS_STR ); mc_addr.sin_port = htons( mc_port ); #endif // Must have a valid pointer to the control object if ( NULL == m_pCtrlObject ) return NULL; // We need to create a clientobject and add this object to the list CClientItem *pClientItem = new CClientItem; if ( NULL == pClientItem ) return NULL; // This is an active client pClientItem->m_bOpen = true; pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_CLIENT_INTERNAL; pClientItem->m_strDeviceName = _("Internal Daemon VSCP Worker Client. Started at "); wxDateTime now = wxDateTime::Now(); pClientItem->m_strDeviceName += now.FormatISODate(); pClientItem->m_strDeviceName += _(" "); pClientItem->m_strDeviceName += now.FormatISOTime(); // Add the client to the Client List m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->addClient( pClientItem ); m_pCtrlObject->m_wxClientMutex.Unlock(); // Clear the filter (Allow everything ) vscp_clearVSCPFilter( &pClientItem->m_filterVSCP ); char szName[ 128 ]; #ifdef WIN32 LPHOSTENT lpLocalHostEntry; #else struct hostent *lpLocalHostEntry; #endif gethostname ( szName, sizeof ( szName ) ); lpLocalHostEntry = gethostbyname ( szName ); if ( NULL == lpLocalHostEntry ) { return NULL; } // Get all local addresses for interface int cntAddr = -1; void *pAddr; unsigned long localaddr[ 16 ]; // max 16 local addresses do { cntAddr++; localaddr[ cntAddr ] = 0; pAddr = lpLocalHostEntry->h_addr_list[ cntAddr ]; if ( NULL != pAddr ) localaddr[ cntAddr ] = * ( ( unsigned long * ) pAddr ); } while ( ( NULL != pAddr ) && ( cntAddr < 16 ) ); // * * * L O O P * * * CLIENTEVENTLIST::compatibility_iterator nodeClient; while ( !TestDestroy() && !m_bQuit ) { // Automation if ( m_pCtrlObject->m_automation.isAutomationEnabled() ) { // Check if automation event should be sent and send it if // that is the case vscpEventEx eventEx; if ( m_pCtrlObject->m_automation.doWork( &eventEx ) ) { m_pCtrlObject->logMsg( wxString::Format( _( "Automation event sent: Class=%d Type=%d\n" ), eventEx.vscp_class, eventEx.vscp_type ), DAEMON_LOGMSG_DEBUG, DAEMON_LOGTYPE_GENERAL ); // Yes event should be sent eventEx.obid = pClientItem->m_clientID; pClientItem->m_guid.writeGUID( eventEx.GUID ); if ( ( VSCP_CLASS1_PROTOCOL == eventEx.vscp_class ) && ( VSCP_TYPE_PROTOCOL_SEGCTRL_HEARTBEAT == eventEx.vscp_type ) ) { // crc8 of VSCP daemon GUID should be indata byte 0 eventEx.data[ 0 ] = vscp_calcCRC4GUIDArray( m_pCtrlObject->m_guid.getGUID() ); // Send event on multicast information channel sendMulticastEventEx( sock_mc, &eventEx, mc_port ); } else if ( ( VSCP_CLASS1_INFORMATION == eventEx.vscp_class ) && ( VSCP_TYPE_INFORMATION_NODE_HEARTBEAT == eventEx.vscp_type ) ) { // Send event on multicast information channel sendMulticastEventEx( sock_mc, &eventEx, mc_port ); } else if ( ( VSCP_CLASS2_INFORMATION == eventEx.vscp_class ) && ( VSCP2_TYPE_INFORMATION_HEART_BEAT == eventEx.vscp_type ) ) { // Copy in server name. memcpy( eventEx.data, m_pCtrlObject->m_strServerName.mbc_str(), MAX( 64, m_pCtrlObject->m_strServerName.Length() ) ); // Send event on multicast information channel sendMulticastEventEx( sock_mc, &eventEx, mc_port ); } vscpEvent *pnewEvent = new vscpEvent; if ( NULL != pnewEvent ) { // Convert event to correct format vscp_convertVSCPfromEx( pnewEvent, &eventEx ); // Statistics pClientItem->m_statistics.cntTransmitData += eventEx.sizeData; pClientItem->m_statistics.cntTransmitFrames++; // There must be room in the send queue if ( m_pCtrlObject->m_maxItemsInClientReceiveQueue > m_pCtrlObject->m_clientOutputQueue.GetCount() ) { m_pCtrlObject->m_mutexClientOutputQueue.Lock(); m_pCtrlObject->m_clientOutputQueue.Append ( pnewEvent ); m_pCtrlObject->m_semClientOutputQueue.Post(); m_pCtrlObject->m_mutexClientOutputQueue.Unlock(); } } } } /////////////////////////////////////////////////////////////////////// // Input queue /////////////////////////////////////////////////////////////////////// int rv = pClientItem->m_clientInputQueue.GetCount(); // Wait for incoming event if ( wxSEMA_TIMEOUT == pClientItem->m_semClientInputQueue.WaitTimeout( 100 ) ) continue; if ( pClientItem->m_clientInputQueue.GetCount() ) { pClientItem->m_mutexClientInputQueue.Lock(); nodeClient = pClientItem->m_clientInputQueue.GetFirst(); vscpEvent *pEvent = nodeClient->GetData(); pClientItem->m_clientInputQueue.DeleteNode( nodeClient ); // Remove the node pClientItem->m_mutexClientInputQueue.Unlock(); if ( NULL == pEvent ) continue; //***************************************** // First check for HIGH END SERVER PROBE (27) // and send out HIGH END SERVER RESPONSE (28) if // received. //***************************************** if ( ( VSCP_CLASS1_PROTOCOL == pEvent->vscp_class ) && ( VSCP_TYPE_PROTOCOL_HIGH_END_SERVER_PROBE == pEvent->vscp_type ) ) { for ( int i=0; i<cntAddr; i++ ) { // Yes this is a "HIGH END SERVER PROBE" // We should send a "HIGH END SERVER RESPONSE" vscpEvent *pnewEvent = new vscpEvent; if ( NULL != pnewEvent ) { pnewEvent->obid = pClientItem->m_clientID; pnewEvent->head = 0; pnewEvent->vscp_class = 0; pnewEvent->vscp_type = 28; pnewEvent->sizeData = 8; pClientItem->m_guid.writeGUID(pnewEvent->GUID); pnewEvent->pdata = new unsigned char[ 8 ]; if ( NULL != pnewEvent->pdata ) { pnewEvent->pdata[ 0 ] = VSCP_DAEMON_SERVER_CAPABILITIES_7; pnewEvent->pdata[ 1 ] = VSCP_DAEMON_SERVER_CAPABILITIES_6; pnewEvent->pdata[ 2 ] = ( localaddr[ i ] >> 24 ); pnewEvent->pdata[ 3 ] = ( localaddr[ i ] >> 16 ); pnewEvent->pdata[ 4 ] = ( localaddr[ i ] >> 8 ); pnewEvent->pdata[ 5 ] = ( localaddr[ i ] & 0xff ); pnewEvent->pdata[ 6 ] = 0x25; // TODO Change can be multiple servers pnewEvent->pdata[ 7 ] = 0x7E; } // Statistics pClientItem->m_statistics.cntTransmitData += pEvent->sizeData; pClientItem->m_statistics.cntTransmitFrames++; // There must be room in the send queue if ( m_pCtrlObject->m_maxItemsInClientReceiveQueue > m_pCtrlObject->m_clientOutputQueue.GetCount() ) { m_pCtrlObject->m_mutexClientOutputQueue.Lock(); m_pCtrlObject->m_clientOutputQueue.Append ( pnewEvent ); m_pCtrlObject->m_semClientOutputQueue.Post(); m_pCtrlObject->m_mutexClientOutputQueue.Unlock(); } } } // for each server address }