Example #1
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;
}