Esempio n. 1
0
bool CVSCPBTDetectWrkTread::sendEvent( vscpEventEx& eventEx )
{
    vscpEvent *pEvent = new vscpEvent();
    if ( NULL != pEvent ) {

        if ( vscp_convertVSCPfromEx( pEvent, &eventEx ) ) {

            // OK send the event
            m_pObj->m_mutexReceiveQueue.Lock();
            m_pObj->m_receiveList.push_back( pEvent );
            m_pObj->m_semReceiveQueue.Post();
            m_pObj->m_mutexReceiveQueue.Unlock();

        }
        else {
            vscp_deleteVSCPevent( pEvent );
#ifndef WIN32
            syslog( LOG_ERR,
                    "%s",
                    ( const char * ) "Faild to convert event." );
#endif
            return false;
        }

    }

    return true;
}
Esempio n. 2
0
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

            }
Esempio n. 3
0
static void ev_handler( struct ns_connection *nc, int ev, void *p )
{
    struct ns_mqtt_message *msg = ( struct ns_mqtt_message * )p;
    Cmqttobj *pmqttobj = ( Cmqttobj *)nc->mgr->user_data;

    switch ( ev ) {

        case NS_CONNECT:
            ns_set_protocol_mqtt( nc );
            ns_send_mqtt_handshake( nc, "vscpd" );
            break;

        case NS_MQTT_CONNACK:
            if ( msg->connack_ret_code != NS_MQTT_CONNACK_ACCEPTED ) {
                printf( "Got mqtt connection error: %d\n", msg->connack_ret_code );
                pmqttobj->m_bQuit = true;
                return;
            }
            
            pmqttobj->m_bConnected = true;

            if ( pmqttobj->m_bSubscribe ) {
                ns_mqtt_subscribe( nc, pmqttobj->m_topic_list, 1, 42 );
            }
            else {
                ;
            }
            break;

        case NS_MQTT_PUBACK:
            printf( "Message publishing acknowledged (msg_id: %d)\n", msg->message_id );
            break;

        case NS_MQTT_SUBACK:
            printf( "Subscription acknowledged, forwarding to '/test'\n" );
            break;

        case NS_MQTT_PUBLISH:
        {
            printf( "Got incoming message %s: %.*s\n", msg->topic, ( int )msg->payload.len, msg->payload.p );
            vscpEventEx eventEx;

            if ( !strcmp( msg->topic, pmqttobj->m_topic.ToAscii() ) ) {

                wxString str = wxString::FromAscii( ( const char * )msg->payload.p );
                if ( vscp_setVscpEventExFromString( &eventEx, str ) ) {

                    vscpEvent *pEvent = new vscpEvent;
                    if ( NULL != pEvent ) {

                        pEvent->sizeData = 0;
                        pEvent->pdata = NULL;

                        if ( vscp_doLevel2FilterEx( &eventEx, &pmqttobj->m_vscpfilter ) ) {

                            if ( vscp_convertVSCPfromEx( pEvent, &eventEx ) ) {
                                pmqttobj->m_mutexReceiveQueue.Lock();
                                pmqttobj->m_receiveList.push_back( pEvent );
                                pmqttobj->m_semReceiveQueue.Post();
                                pmqttobj->m_mutexReceiveQueue.Unlock();
                            }
                            else {

                            }
                        }
                        else {
                            vscp_deleteVSCPevent( pEvent );
                        }
                    }
                }
            }
        }
        break;

        case NS_CLOSE:
            printf( "Connection closed\n" );
            pmqttobj->m_bConnected = false;
            pmqttobj->m_bQuit = true;
    }

}
void *
CWrkReadThread::Entry()
{
	pcap_t *fp;
	char errbuf[ PCAP_ERRBUF_SIZE ];
	//uint8_t packet[ 512 ];

	// First log on to the host and get configuration 
	// variables

	if (m_srv.doCmdOpen(m_pObj->m_host,
			m_pObj->m_username,
			m_pObj->m_password) <= 0) {
		return NULL;
	}

	// Find the channel id
	m_srv.doCmdGetChannelID(&m_pObj->m_ChannelIDtx);

	// It is possible that there is configuration data the server holds 
	// that we need to read in. 
	// We look for 
	//      prefix_interface Communication interface to work on
	//      prefix_localmac MAC address to use for outgoing packets
	//      prefix_filter to find a filter. A string is expected.
	//      prefix_mask to find a mask. A string is expected.

	/*	
		// Interface
		wxString varInterface;
		if (m_srv.getVariableString(m_pObj->m_prefix + _T("_interface"), &varInterface)) {
			m_pObj->m_interface = varInterface;
		}

		wxString varLocalMac;
		if (m_srv.getVariableString(m_pObj->m_prefix + _T("_localmac"), &varLocalMac)) {
			varLocalMac.MakeUpper();
			wxStringTokenizer tkz(varLocalMac, ":\n");
			for (int i = 0; i < 6; i++) {
				if (tkz.HasMoreTokens()) break;
				wxString str = _("0X") + tkz.GetNextToken();
				m_pObj->m_localMac[ i ] = readStringValue(str);
				m_pObj->m_localGUIDtx.setAt((9 + i), m_pObj->m_localMac[ i ]);
				m_pObj->m_localGUIDrx.setAt((9 + i), m_pObj->m_localMac[ i ]);
			}
		}

	 */
	// We want to use our own Ethernet based GUID for this interface
	//wxString strGUID;
	//m_pObj->m_localGUIDtx.toString(strGUID);
	//m_srv.doCmdSetGUID((const char *) strGUID.ToAscii());

	// Open the adapter 
	if ((fp = pcap_open_live(m_pObj->m_interface.ToAscii(), // name of the device
			65536, // portion of the packet to capture. It doesn't matter in this case 
			1, // promiscuous mode (nonzero means promiscuous)
			1000, // read timeout
			errbuf // error buffer
			)) == NULL) {
		//fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]);
		return NULL;
	}

	int rv;
	struct pcap_pkthdr *header;
	const u_char *pkt_data;

	while (!TestDestroy() &&
			!m_pObj->m_bQuit &&
			(rv = pcap_next_ex(fp, &header, &pkt_data)) >= 0) {

		// Check for timeout            
		if (0 == rv) continue;

		// Check if this is VSCP
		if ((0x25 == pkt_data[ 12 ]) &&
				(0x7e == pkt_data[ 13 ])) {

			// We have a packet - send it as a VSCP event    
			vscpEventEx eventex;

			eventex.head = pkt_data[ 15 ] & 0xe0; // Priority

			eventex.GUID[ 0 ] = 0xff; // Ethernet predefined  GUID
			eventex.GUID[ 1 ] = 0xff;
			eventex.GUID[ 2 ] = 0xff;
			eventex.GUID[ 3 ] = 0xff;
			eventex.GUID[ 4 ] = 0xff;
			eventex.GUID[ 5 ] = 0xff;
			eventex.GUID[ 6 ] = 0xff;
			eventex.GUID[ 7 ] = 0xfe;
			eventex.GUID[ 8 ] = pkt_data[ 6 ]; // Source MAC address
			eventex.GUID[ 9 ] = pkt_data[ 7 ];
			eventex.GUID[ 10 ] = pkt_data[ 8 ];
			eventex.GUID[ 11 ] = pkt_data[ 9 ];
			eventex.GUID[ 12 ] = pkt_data[ 10 ];
			eventex.GUID[ 13 ] = pkt_data[ 11 ];
			eventex.GUID[ 14 ] = pkt_data[ 19 ]; // Device sub address
			eventex.GUID[ 15 ] = pkt_data[ 20 ];

			eventex.timestamp = (pkt_data[ 21 ] << 24) +
					(pkt_data[ 22 ] << 16) +
					(pkt_data[ 23 ] << 8) +
					pkt_data[ 24 ];

			eventex.obid = (pkt_data[ 25 ] << 24) +
					(pkt_data[ 26 ] << 16) +
					(pkt_data[ 27 ] << 8) +
					pkt_data[ 28 ];

			eventex.vscp_class = (pkt_data[ 29 ] << 8) +
                    pkt_data[ 30 ];

			eventex.vscp_type = (pkt_data[ 31 ] << 8) +
					pkt_data[ 32 ];

			eventex.sizeData = (pkt_data[ 33 ] << 8) +
					pkt_data[ 34 ];

			// If the packet is smaller then the set datasize just 
			// disregard it
			if ((eventex.sizeData + 35) > (uint16_t) header->len) continue;

			for (int i = 0; i < eventex.sizeData; i++) {
				eventex.data[ i ] = pkt_data[ 35 + i ];
            }

            vscpEvent *pEvent = new vscpEvent;
            if (NULL != pEvent) {
                
                vscp_convertVSCPfromEx(pEvent, &eventex);

                if (vscp_doLevel2FilterEx( &eventex, &m_pObj->m_vscpfilter)) {
                    m_pObj->m_mutexReceiveQueue.Lock();
                    m_pObj->m_receiveList.push_back(pEvent);
                    m_pObj->m_semReceiveQueue.Post();
                    m_pObj->m_mutexReceiveQueue.Unlock();
                }
                else {
                    vscp_deleteVSCPevent(pEvent);
                }
            }

        }

	} // work loop   

	// Close listner
	pcap_close(fp);

	// Close the channel
	//m_srv.doCmdClose();

	return NULL;
}