예제 #1
0
extern "C" long
CanalOpen(const char *pDevice, unsigned long flags)
{
    long h               = CANAL_ERROR_SUB_DRIVER;
    unsigned long filter = 0, mask = 0;
    bool bFilter = false, bMask = false;
    std::string str;
    std::string strDevice(pDevice);

    std::deque<std::string> tokens;
    vscp_split(tokens, strDevice, ";");

    // Get possible filter
    if (!tokens.empty()) {
        str = tokens.front();
        tokens.pop_front();
        if (0 != str.size()) {
            filter = vscp_readStringValue(str);
        }
    }

    // Get possible mask
    if (!tokens.empty()) {
        str = tokens.front();
        tokens.pop_front();
        if (0 != str.size()) {
            mask = vscp_readStringValue(str);
        }
    }

    VscpRemoteTcpIf *pvscpif = new VscpRemoteTcpIf();
    if (NULL != pvscpif) {

        if (pvscpif->doCmdOpen(strDevice, flags)) {

            if (!(h = addDriverObject(pvscpif))) {
                delete pvscpif;
            } else {

                if (bFilter) {
                    pvscpif->doCmdFilter(filter);
                }

                if (bMask) {
                    pvscpif->doCmdMask(mask);
                }
            }

        } else {
            delete pvscpif;
        }
    }

    return h;
}
예제 #2
0
파일: canalconfobj.cpp 프로젝트: ajje/vscp
void WizardPageFlagsConfig::OnWizardPageChanging( wxWizardEvent& event )
{
    uint32_t mask = ( 1 << m_pItem->m_width ) - 1;
    mask = mask << m_pItem->m_pos;

    if ( event.GetDirection() ) {  // Forward

        if ( flagtype_value == m_pItem->m_type ) {
            wxString str = m_textField->GetValue();
            if ( !str.IsNumber() ) {
                event.Veto();
            }
            else {
                m_value = vscp_readStringValue( str );
                m_value = ( m_value << m_pItem->m_pos ) & mask;
            }
        }
        else if ( flagtype_choice == m_pItem->m_type ) {
            m_value = m_listBox->GetSelection();
            m_value = ( m_value << m_pItem->m_pos ) & mask;
        }
        else {  // Boolean
            m_value = ( m_boolChoice->GetValue() ? 1 : 0 );
            m_value = ( m_value << m_pItem->m_pos ) & mask;
        }

    }
    else { // Backward

    }
}
예제 #3
0
bool
Cmqttobj::open( const char *pUsername,
                    const char *pPassword,
                    const char *pHost,
                    const char *pPrefix,
                    const char *pConfig)
{
	bool rv = true;
	wxString str;
	wxString wxstr = wxString::FromAscii(pConfig);

	m_username = wxString::FromAscii(pUsername);
	m_password = wxString::FromAscii(pPassword);
	m_host = wxString::FromAscii(pHost);
	m_prefix = wxString::FromAscii(pPrefix);

	// Parse the configuration string. It should
	// have the following form
	// path
	// 
	wxStringTokenizer tkz(wxString::FromAscii(pConfig), _(";\n"));

	// Check if we should publish or subscribe
	if ( tkz.HasMoreTokens() ) {
		// Check for subscribe/publish
		str = tkz.GetNextToken();
		str.Trim();
		str.Trim(false);
		str.MakeUpper();
		if ( wxNOT_FOUND != str.Find( _("PUBLISH") ) ) {
			m_bSubscribe = false;
		}
	}

	// Get topic from configuration string
	if ( tkz.HasMoreTokens() ) {
		m_topic = tkz.GetNextToken();
	}

	// Get MQTT host from configuration string
	if ( tkz.HasMoreTokens() ) {
		m_hostMQTT = tkz.GetNextToken();
	}

	// Get MQTT host port from configuration string
	if ( tkz.HasMoreTokens() ) {
		m_portMQTT = vscp_readStringValue(tkz.GetNextToken());
	}

	// Get MQTT user from configuration string
	if ( tkz.HasMoreTokens() ) {
		m_usernameMQTT = tkz.GetNextToken();
	}

	// Get MQTT password from configuration string
	if ( tkz.HasMoreTokens() ) {
		m_passwordMQTT = tkz.GetNextToken();
	}

	// Get MQTT keep alive from configuration string
	if ( tkz.HasMoreTokens() ) {
		m_keepalive = vscp_readStringValue(tkz.GetNextToken());
	}

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

	if ( VSCP_ERROR_SUCCESS !=  m_srv.doCmdOpen( m_host,
                                                    m_username,
                                                    m_password) ) {
#ifndef WIN32
		syslog(LOG_ERR,
				"%s",
				(const char *) "Unable to connect to VSCP TCP/IP interface. Terminating!");
#endif
		return false;
	}

	// Find the channel id
	uint32_t ChannelID;
	m_srv.doCmdGetChannelID( &ChannelID );

	// The server should hold configuration data for each sensor
	// we want to monitor.
	// 
	// We look for 
	//
	//	 _type	- “subscribe” to subscribe to a MQTT topic. ”publish” to 
	//				publish events to a MQTT topic. Defaults to “subscribe”.
	//
	//	 _topic	- This is a text string identifying the topic. It is 
	//				recommended that this string starts with “vscp/”. 
	//						Defaults to “vscp”
	//
    //	 _qos	- MQTT QOS value. Defaults to 0. 
    //
	//	 _host	- IP address + port or a DNS resolvable address + port on the 
    //              form host:port to the remote host. 
	//				Mandatory and must be declared either in the configuration 
	//				string or in this variable. Defaults to “localhost:1883”
	//
	//	 _user - Username used to log in on the remote sever. 
	//				Defaults to empty. 
	//
	//	 _password - Password used to login on the remote server. 
	//				Defaults to empty.
	//
	//	 _keepalive - Keepalive value for channel. Defaults to 60.
	//
	//   _filter - Standard VSCP filter in string form. 
	//				   1,0x0000,0x0006,
	//				   ff:ff:ff:ff:ff:ff:ff:01:00:00:00:00:00:00:00:00
	//				as priority,class,type,GUID
	//				Used to filter what events that is received from 
	//				the mqtt interface. If not give all events 
	//				are received.
	//	 _mask - Standard VSCP mask in string form.
	//				   1,0x0000,0x0006,
	//				   ff:ff:ff:ff:ff:ff:ff:01:00:00:00:00:00:00:00:00
	//				as priority,class,type,GUID
	//				Used to filter what events that is received from 
	//				the mqtt interface. If not give all events 
	//				are received. 
	//

	wxString strName = m_prefix +
			wxString::FromAscii("_type");
	m_srv.getVariableString(strName, &str);

	// Check for subscribe/publish
	str = tkz.GetNextToken();
	str.Trim();
	str.Trim(false);
	str.MakeUpper();
	if ( wxNOT_FOUND != str.Find(_("publish") ) ) {
		m_bSubscribe = false;
	}

	strName = m_prefix +
			wxString::FromAscii("_topic");
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableString( strName, &str ) ) {
        m_topic = str;
    }

	strName = m_prefix +
			wxString::FromAscii("_host");
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableString( strName, &m_hostMQTT ) ) {
        m_hostMQTT = str;
    }

	strName = m_prefix +
			wxString::FromAscii("_username");
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableString( strName, &str ) ) {
        m_usernameMQTT = str;
    }

	strName = m_prefix +
			wxString::FromAscii("_password");
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableString( strName, &m_passwordMQTT ) ) {
        m_passwordMQTT = str;
    }

	strName = m_prefix +
			wxString::FromAscii("_keepalive");
    int intval;
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableInt( strName, &intval ) ) {
        m_keepalive = intval;
    }

    strName = m_prefix +
        wxString::FromAscii( "_qos" );
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableInt( strName, &intval ) ) {
        m_topic_list[ 0 ].qos = intval;
    }

	strName = m_prefix +
			wxString::FromAscii("_filter");
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableString( strName, &str ) ) {
		vscp_readFilterFromString(&m_vscpfilter, str);
    }

	strName = m_prefix +
			wxString::FromAscii("_mask");
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableString( strName, &str ) ) {
		vscp_readMaskFromString(&m_vscpfilter, str);
	}
    
    strName = m_prefix +
			wxString::FromAscii("_simplify");
    if ( VSCP_ERROR_SUCCESS == m_srv.getVariableString( strName, &str ) ) {
        m_simplify = str;
    }
    
    if ( m_simplify.Length() ) {
        
        m_bSimplify = true; 
        
        wxStringTokenizer tkzSimple( m_simplify, _(",\n"));
        
        // simple class
        if ( tkzSimple.HasMoreTokens() ) {
            m_simple_class = vscp_readStringValue(tkzSimple.GetNextToken());
        }
        
        // simple type
        if ( tkzSimple.HasMoreTokens() ) {
            m_simple_type = vscp_readStringValue(tkzSimple.GetNextToken());
        }
        
        // simple coding
        if ( tkzSimple.HasMoreTokens() ) {
            m_simple_coding = vscp_readStringValue(tkzSimple.GetNextToken());
        }
        
        // simple zone
        if ( tkzSimple.HasMoreTokens() ) {
            m_simple_zone = vscp_readStringValue(tkzSimple.GetNextToken());
        }
        
        // simple subzone
        if (tkzSimple.HasMoreTokens()) {
            m_simple_subzone = vscp_readStringValue(tkzSimple.GetNextToken());
        }
        
    }
    else {
        m_bSimplify = false;
    }

    if ( m_bSubscribe ) {
        m_topic_list[ 0 ].topic = new char( m_topic.Length() + 1 );
        if ( NULL != m_topic_list[ 0 ].topic ) {
            memset( (void *)m_topic_list[ 0 ].topic, 0, m_topic.Length() + 1 );
            memcpy( ( void * )m_topic_list[ 0 ].topic, m_topic.mbc_str(), m_topic.Length() );
        }
    }
    
	// Close the channel
	m_srv.doCmdClose();

	// start the worker thread
	m_pthreadWork = new CWrkThread();
	if (NULL != m_pthreadWork) {
		m_pthreadWork->m_pObj = this;
		m_pthreadWork->Create();
		m_pthreadWork->Run();
	}
	else {
		rv = false;
	}

	return rv;
}
예제 #4
0
void *
deviceThread(void *pData)
{
    const char *dlsym_error;

    CDeviceItem *pDevItem = (CDeviceItem *)pData;
    if (NULL == pDevItem) {
        syslog(LOG_CRIT, "No device item defined. Aborting device thread!");
        return NULL;
    }

    // Must have a valid pointer to the control object
    CControlObject *pCtrlObj = pDevItem->m_pCtrlObject;
    if (NULL == pCtrlObj) {
        syslog(LOG_CRIT, "No control object defined. Aborting device thread!");
        return NULL;
    }

    // We need to create a clientobject and add this object to the list
    CClientItem *pClientItem = pDevItem->m_pClientItem = new CClientItem;
    if (NULL == pClientItem) {
        return NULL;
    }

    // This is now an active Client
    pClientItem->m_bOpen = true;
    if (VSCP_DRIVER_LEVEL1 == pDevItem->m_driverLevel) {
        pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_DRIVER_LEVEL1;
    } else if (VSCP_DRIVER_LEVEL2 == pDevItem->m_driverLevel) {
        pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_DRIVER_LEVEL2;
    } else if (VSCP_DRIVER_LEVEL3 == pDevItem->m_driverLevel) {
        pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_DRIVER_LEVEL3;
    }

    char datebuf[80];
    time_t now = time(NULL);
    vscp_getTimeString(datebuf, sizeof(datebuf), &now);
    pClientItem->m_strDeviceName = pDevItem->m_strName;
    pClientItem->m_strDeviceName += "|Started at ";
    pClientItem->m_strDeviceName += datebuf;

    syslog(LOG_DEBUG,
           "Devicethread: Starting %s",
           pClientItem->m_strDeviceName.c_str());

    // Add the client to the Client List
    pthread_mutex_lock(&pCtrlObj->m_clientList.m_mutexItemList);
    if (!pCtrlObj->addClient(pClientItem,
                             pDevItem->m_interface_guid.getClientID())) {
        // Failed to add client
        delete pDevItem->m_pClientItem;
        pDevItem->m_pClientItem = NULL;

        pthread_mutex_unlock(&pCtrlObj->m_clientList.m_mutexItemList);
        syslog(LOG_ERR,
               "Devicethread: Failed to add client. Terminating thread.");
        return NULL;
    }
    pthread_mutex_unlock(&pCtrlObj->m_clientList.m_mutexItemList);

    // Client now have GUID set to server GUID + channel id
    // If device has a non NULL GUID replace the client GUID preserving
    // the channel id with that GUID
    if (!pClientItem->m_guid.isNULL()) {
        memcpy(
          pClientItem->m_guid.m_id, pDevItem->m_interface_guid.getGUID(), 12);
    }

    void *hdll;
    if (VSCP_DRIVER_LEVEL3 != pDevItem->m_driverLevel) {
        // Load dynamic library
        hdll = dlopen(pDevItem->m_strPath.c_str(), RTLD_LAZY);
        if (!hdll) {
            syslog(LOG_ERR,
                   "Devicethread: Unable to load dynamic library. path = %s",
                   pDevItem->m_strPath.c_str());
            return NULL;
        }
    } else { // Level III driver

        //  Startup Level III driver
        std::string executable = pDevItem->m_strPath;

        pid_t pid = fork();
        if (pid == -1) {
            syslog(LOG_ERR,
                   "Failed to start level III driver %s (fork).",
                   pDevItem->m_strName.c_str());
        } else if (pid == 0) {

            // we're in child

            // Set process group to child process' pid.  Then killing -pid
            // of the parent will kill the process and all of its children.
            setsid();

            // Arguments:    TODO
            //      user
            //      password
            //      config parameters...
            // execvp( *argv, const_cast<char**>(argv) );

            // Wait on child
            int status;
            waitpid(pid, &status, 0);
        }
    }

    if (VSCP_DRIVER_LEVEL1 == pDevItem->m_driverLevel) {

        // Now find methods in library
        syslog(
          LOG_INFO, "Loading level I driver: %s", pDevItem->m_strName.c_str());

        // * * * * CANAL OPEN * * * *
        pDevItem->m_proc_CanalOpen =
          (LPFNDLL_CANALOPEN)dlsym(hdll, "CanalOpen");
        const char *dlsym_error = dlerror();
        dlsym_error             = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_DEBUG,
                   "%s : Unable to get dl entry for CanalOpen.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * CANAL CLOSE * * * *
        pDevItem->m_proc_CanalClose =
          (LPFNDLL_CANALCLOSE)dlsym(hdll, "CanalClose");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalClose.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL GETLEVEL * * * *
        pDevItem->m_proc_CanalGetLevel =
          (LPFNDLL_CANALGETLEVEL)dlsym(hdll, "CanalGetLevel");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalGetLevel.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL SEND * * * *
        pDevItem->m_proc_CanalSend =
          (LPFNDLL_CANALSEND)dlsym(hdll, "CanalSend");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalSend.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL DATA AVAILABLE * * * *
        pDevItem->m_proc_CanalDataAvailable =
          (LPFNDLL_CANALDATAAVAILABLE)dlsym(hdll, "CanalDataAvailable");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalDataAvailable.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL RECEIVE * * * *
        pDevItem->m_proc_CanalReceive =
          (LPFNDLL_CANALRECEIVE)dlsym(hdll, "CanalReceive");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalReceive.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL GET STATUS * * * *
        pDevItem->m_proc_CanalGetStatus =
          (LPFNDLL_CANALGETSTATUS)dlsym(hdll, "CanalGetStatus");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalGetStatus.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL GET STATISTICS * * * *
        pDevItem->m_proc_CanalGetStatistics =
          (LPFNDLL_CANALGETSTATISTICS)dlsym(hdll, "CanalGetStatistics");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalGetStatistics.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL SET FILTER * * * *
        pDevItem->m_proc_CanalSetFilter =
          (LPFNDLL_CANALSETFILTER)dlsym(hdll, "CanalSetFilter");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalSetFilter.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL SET MASK * * * *
        pDevItem->m_proc_CanalSetMask =
          (LPFNDLL_CANALSETMASK)dlsym(hdll, "CanalSetMask");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalSetMask.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL GET VERSION * * * *
        pDevItem->m_proc_CanalGetVersion =
          (LPFNDLL_CANALGETVERSION)dlsym(hdll, "CanalGetVersion");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalGetVersion.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL GET DLL VERSION * * * *
        pDevItem->m_proc_CanalGetDllVersion =
          (LPFNDLL_CANALGETDLLVERSION)dlsym(hdll, "CanalGetDllVersion");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalGetDllVersion.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // * * * * CANAL GET VENDOR STRING * * * *
        pDevItem->m_proc_CanalGetVendorString =
          (LPFNDLL_CANALGETVENDORSTRING)dlsym(hdll, "CanalGetVendorString");
        dlsym_error = dlerror();
        if (dlsym_error) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalGetVendorString.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        // ******************************
        //     Generation 2 Methods
        // ******************************

        // * * * * CANAL BLOCKING SEND * * * *
        pDevItem->m_proc_CanalBlockingSend =
          (LPFNDLL_CANALBLOCKINGSEND)dlsym(hdll, "CanalBlockingSend");
        dlsym_error = dlerror();
        if (dlsym_error) {
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalBlockingSend. Probably "
                   "Generation 1 driver.",
                   pDevItem->m_strName.c_str());
            pDevItem->m_proc_CanalBlockingSend = NULL;
        }

        // * * * * CANAL BLOCKING RECEIVE * * * *
        pDevItem->m_proc_CanalBlockingReceive =
          (LPFNDLL_CANALBLOCKINGRECEIVE)dlsym(hdll, "CanalBlockingReceive");
        dlsym_error = dlerror();
        if (dlsym_error) {
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalBlockingReceive. "
                   "Probably Generation 1 driver.",
                   pDevItem->m_strName.c_str());
            pDevItem->m_proc_CanalBlockingReceive = NULL;
        }

        // * * * * CANAL GET DRIVER INFO * * * *
        pDevItem->m_proc_CanalGetdriverInfo =
          (LPFNDLL_CANALGETDRIVERINFO)dlsym(hdll, "CanalGetDriverInfo");
        dlsym_error = dlerror();
        if (dlsym_error) {
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for CanalGetDriverInfo. "
                   "Probably Generation 1 driver.",
                   pDevItem->m_strName.c_str());
            pDevItem->m_proc_CanalGetdriverInfo = NULL;
        }

        // Open the device
        pDevItem->m_openHandle = pDevItem->m_proc_CanalOpen(
          (const char *)pDevItem->m_strParameter.c_str(),
          pDevItem->m_DeviceFlags);

        // Check if the driver opened properly
        if (pDevItem->m_openHandle <= 0) {
            syslog(LOG_ERR,
                   "Failed to open driver. Will not use it! [%s] ",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL;
        }

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level I Driver open.",
                   pDevItem->m_strName.c_str());
        }

        // Get Driver Level
        pDevItem->m_driverLevel =
          pDevItem->m_proc_CanalGetLevel(pDevItem->m_openHandle);

        //  * * * Level I Driver * * *

        // Check if blocking driver is available
        if (NULL != pDevItem->m_proc_CanalBlockingReceive) {

            // * * * * Blocking version * * * *

            if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
                syslog(LOG_DEBUG,
                       "%s: [Device tread] Level I blocking version.",
                       pDevItem->m_strName.c_str());
            }

            /////////////////////////////////////////////////////////////////////////////
            //                      Device write worker thread
            /////////////////////////////////////////////////////////////////////////////

            if (pthread_create(&pDevItem->m_level1WriteThread,
                               NULL,
                               deviceLevel1WriteThread,
                               pDevItem)) {
                syslog(LOG_CRIT,
                       "%s: Unable to run the device write worker thread.",
                       pDevItem->m_strName.c_str());
                // pDevItem->m_openHandle = pDevItem->m_proc_CanalOpen();
                dlclose(hdll);
                return NULL;
            }

            /////////////////////////////////////////////////////////////////////////////
            // Device read worker thread
            /////////////////////////////////////////////////////////////////////////////
            if (pthread_create(&pDevItem->m_level1ReceiveThread,
                               NULL,
                               deviceLevel1ReceiveThread,
                               pDevItem)) {
                syslog(LOG_CRIT,
                       "%s: Unable to run the device read worker thread.",
                       pDevItem->m_strName.c_str());
                pDevItem->m_bQuit = true;
                pthread_join(pDevItem->m_level1WriteThread, NULL);
                // pDevItem->m_openHandle = pDevItem->m_proc_CanalOpen();
                dlclose(hdll);
                return NULL;
            }

            // Just sit and wait until the end of the world as we know it...
            while (!pDevItem->m_bQuit) {
                sleep(1);
            }

            // Signal worker threads to quit
            pDevItem->m_bQuit = true;

            if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
                syslog(LOG_DEBUG,
                       "%s: [Device tread] Level I work loop ended.",
                       pDevItem->m_strName.c_str());
            }

            // Wait for workerthreads to abort
            pthread_join(pDevItem->m_level1WriteThread, NULL);
            pthread_join(pDevItem->m_level1ReceiveThread, NULL);
        } else {

            // * * * * Non blocking version * * * *

            if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
                syslog(LOG_DEBUG,
                       "%s: [Device tread] Level I NON Blocking version.",
                       pDevItem->m_strName.c_str());
            }

            bool bActivity;
            while (pDevItem->m_bQuit) {

                bActivity = false;
                /////////////////////////////////////////////////////////////////////////////
                //                           Receive from device
                /////////////////////////////////////////////////////////////////////////////
                canalMsg msg;
                if (pDevItem->m_proc_CanalDataAvailable(
                      pDevItem->m_openHandle)) {

                    if (CANAL_ERROR_SUCCESS ==
                        pDevItem->m_proc_CanalReceive(pDevItem->m_openHandle,
                                                      &msg)) {

                        bActivity = true;

                        // There must be room in the receive queue
                        if (pCtrlObj->m_maxItemsInClientReceiveQueue >
                            pCtrlObj->m_clientOutputQueue.size()) {

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

                                // Set driver GUID if set
                                /*if ( pDevItem->m_interface_guid.isNULL() ) {
                                    pDevItem->m_interface_guid.writeGUID(
                                pvscpEvent->GUID );
                                }
                                else {
                                    // If no driver GUID set use interface GUID
                                    pItem->m_guid.writeGUID( pvscpEvent->GUID );
                                }*/

                                // Convert CANAL message to VSCP event
                                vscp_convertCanalToEvent(
                                  pvscpEvent, &msg, pClientItem->m_guid.m_id);

                                pvscpEvent->obid = pClientItem->m_clientID;

                                pthread_mutex_lock(
                                  &pCtrlObj->m_mutexClientOutputQueue);
                                pCtrlObj->m_clientOutputQueue.push_back(
                                  pvscpEvent);
                                sem_post(&pCtrlObj->m_semClientOutputQueue);
                                pthread_mutex_unlock(
                                  &pCtrlObj->m_mutexClientOutputQueue);
                            }
                        }
                    }
                } // data available

                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
                //          Send messages (if any) in the output queue
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

                // Check if there is something to send
                if (pClientItem->m_clientInputQueue.size()) {

                    bActivity = true;

                    std::deque<vscpEvent *>::iterator it;

                    pthread_mutex_lock(&pClientItem->m_mutexClientInputQueue);
                    vscpEvent *pqueueEvent =
                      pClientItem->m_clientInputQueue.front();
                    pthread_mutex_lock(&pClientItem->m_mutexClientInputQueue);

                    // Trow away Level II event on Level I interface
                    if ((CLIENT_ITEM_INTERFACE_TYPE_DRIVER_LEVEL1 ==
                         pClientItem->m_type) &&
                        (pqueueEvent->vscp_class > 512)) {
                        // Remove the event and the node
                        pClientItem->m_clientInputQueue.pop_front();
                        syslog(LOG_ERR,
                               "Level II event on Level I queue thrown away. "
                               "class=%d, type=%d",
                               pqueueEvent->vscp_class,
                               pqueueEvent->vscp_type);
                        vscp_deleteVSCPevent(pqueueEvent);
                        continue;
                    }

                    canalMsg canalMsg;
                    vscp_convertEventToCanal(&canalMsg, pqueueEvent);
                    if (CANAL_ERROR_SUCCESS ==
                        pDevItem->m_proc_CanalSend(pDevItem->m_openHandle,
                                                   &canalMsg)) {
                        // Remove the event and the node
                        pClientItem->m_clientInputQueue.pop_front();
                        delete pqueueEvent;
                    } else {
                        // Another try
                        // pCtrlObj->m_semClientOutputQueue.Post();
                        // vscp_deleteVSCPevent(pqueueEvent);  TODO ????
                    }

                } // events

                if (!bActivity) {
                    usleep(100000); // 100 ms
                }

                bActivity = false;

            } // while working - non blocking

        } // if blocking/non blocking

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level I Work loop ended.",
                   pDevItem->m_strName.c_str());
        }

        // Close CANAL channel
        pDevItem->m_proc_CanalClose(pDevItem->m_openHandle);

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level I Closed.",
                   pDevItem->m_strName.c_str());
        }

    level1_driver_exit:

        pDevItem->m_bQuit = true;
        pthread_join(pDevItem->m_level1WriteThread, NULL);
        pthread_join(pDevItem->m_level1ReceiveThread, NULL);

        dlclose(hdll);

    } else if (VSCP_DRIVER_LEVEL2 == pDevItem->m_driverLevel) {

        // Now find methods in library
        syslog(LOG_INFO,
               "Loading level II driver: <%s>",
               pDevItem->m_strName.c_str());

        // * * * * VSCP OPEN * * * *
        if (NULL == (pDevItem->m_proc_VSCPOpen =
                       (LPFNDLL_VSCPOPEN)dlsym(hdll, "VSCPOpen"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPOpen.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP CLOSE * * * *
        if (NULL == (pDevItem->m_proc_VSCPClose =
                       (LPFNDLL_VSCPCLOSE)dlsym(hdll, "VSCPClose"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPClose.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP BLOCKINGSEND * * * *
        if (NULL ==
            (pDevItem->m_proc_VSCPBlockingSend =
               (LPFNDLL_VSCPBLOCKINGSEND)dlsym(hdll, "VSCPBlockingSend"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPBlockingSend.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP BLOCKINGRECEIVE * * * *
        if (NULL == (pDevItem->m_proc_VSCPBlockingReceive =
                       (LPFNDLL_VSCPBLOCKINGRECEIVE)dlsym(
                         hdll, "VSCPBlockingReceive"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPBlockingReceive.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP GETLEVEL * * * *
        if (NULL == (pDevItem->m_proc_VSCPGetLevel =
                       (LPFNDLL_VSCPGETLEVEL)dlsym(hdll, "VSCPGetLevel"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPGetLevel.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP GET DLL VERSION * * * *
        if (NULL ==
            (pDevItem->m_proc_VSCPGetDllVersion =
               (LPFNDLL_VSCPGETDLLVERSION)dlsym(hdll, "VSCPGetDllVersion"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPGetDllVersion.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP GET VENDOR STRING * * * *
        if (NULL == (pDevItem->m_proc_VSCPGetVendorString =
                       (LPFNDLL_VSCPGETVENDORSTRING)dlsym(
                         hdll, "VSCPGetVendorString"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPGetVendorString.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP GET DRIVER INFO * * * *
        if (NULL ==
            (pDevItem->m_proc_CanalGetdriverInfo =
               (LPFNDLL_VSCPGETVENDORSTRING)dlsym(hdll, "VSCPGetDriverInfo"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPGetDriverInfo.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP GET WEB PAGE TEMPLATE * * * *
        if (NULL == (pDevItem->m_proc_VSCPGetWebPageTemplate =
                       (LPFNDLL_VSCPGETWEBPAGETEMPLATE)dlsym(
                         hdll, "VSCPGetWebPageTemplate"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPGetWebPageTemplate.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP GET WEB PAGE INFO * * * *
        if (NULL ==
            (pDevItem->m_proc_VSCPGetWebPageInfo =
               (LPFNDLL_VSCPGETWEBPAGEINFO)dlsym(hdll, "VSCPGetWebPageInfo"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPGetWebPageInfo.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        // * * * * VSCP WEB PAGE UPDATE * * * *
        if (NULL ==
            (pDevItem->m_proc_VSCPWebPageupdate =
               (LPFNDLL_VSCPWEBPAGEUPDATE)dlsym(hdll, "VSCPWebPageupdate"))) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: Unable to get dl entry for VSCPWebPageupdate.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: Discovered all methods\n",
                   pDevItem->m_strName.c_str());
        }

        // Username, password, host and port can be set in configuration file.
        // Read in them here if they are.
        std::string strHost("127.0.0.1");
        short port = 9598;

        std::deque<std::string> tokens;
        vscp_split(tokens, pDevItem->m_strParameter, ";");
        if (false == tokens.empty()) {

            CVariable variable;

            // Get prefix
            std::string prefix = tokens.front();
            tokens.pop_front();

            // Check if username is specified in the configuration file
            CUserItem *pAdminUser =
              pDevItem->m_pCtrlObject->m_userList.getUser(USER_ID_ADMIN);
            if (pCtrlObj->m_variables.find(
                  pDevItem->m_strName + "_username", pAdminUser, variable)) {
                std::string str;
                if (VSCP_DAEMON_VARIABLE_CODE_STRING == variable.getType()) {
                    str                        = variable.getValue();
                    pCtrlObj->m_driverUsername = str;
                }
            }

            // Check if password is specified in the configuration file
            if (pCtrlObj->m_variables.find(
                  pDevItem->m_strName + "_password", pAdminUser, variable)) {
                std::string str;
                if (VSCP_DAEMON_VARIABLE_CODE_STRING == variable.getType()) {
                    str                        = variable.getValue();
                    pCtrlObj->m_driverPassword = str;
                }
            }

            // Check if host is specified in the configuration file
            if (pCtrlObj->m_variables.find(
                  pDevItem->m_strName + "_host", pAdminUser, variable)) {
                std::string str;
                if (VSCP_DAEMON_VARIABLE_CODE_STRING == variable.getType()) {
                    str     = variable.getValue();
                    strHost = str;
                }
            }

            // Check if host is specified in the configuration file
            if (pCtrlObj->m_variables.find(
                  pDevItem->m_strName + "_port", pAdminUser, variable)) {
                std::string str;
                if (VSCP_DAEMON_VARIABLE_CODE_INTEGER == variable.getType()) {
                    str  = variable.getValue();
                    port = vscp_readStringValue(str);
                }
            }
        }

        // Open up the driver
        pDevItem->m_openHandle = pDevItem->m_proc_VSCPOpen(
          pCtrlObj->m_driverUsername.c_str(),
          (const char *)pCtrlObj->m_driverPassword.c_str(),
          (const char *)strHost.c_str(),
          port,
          (const char *)pDevItem->m_strName.c_str(),
          (const char *)pDevItem->m_strParameter.c_str());

        if (0 == pDevItem->m_openHandle) {
            // Free the library
            syslog(LOG_ERR,
                   "%s: [Device tread] Unable to open VSCP "
                   "driver (check username/password/path/"
                   "rights). Possible additional info from driver "
                   "in syslog.",
                   pDevItem->m_strName.c_str());
            return NULL;
        }

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level II Open.",
                   pDevItem->m_strName.c_str());
        }

        /////////////////////////////////////////////////////////////////////////////
        // Device write worker thread
        /////////////////////////////////////////////////////////////////////////////

        if (pthread_create(&pDevItem->m_level2WriteThread,
                           NULL,
                           deviceLevel2WriteThread,
                           pDevItem)) {
            syslog(LOG_CRIT,
                   "%s: Unable to run the device Level II write worker thread.",
                   pDevItem->m_strName.c_str());
            dlclose(hdll);
            return NULL; // TODO close dll
        }

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level II Write thread created.",
                   pDevItem->m_strName.c_str());
        }

        /////////////////////////////////////////////////////////////////////////////
        // Device read worker thread
        /////////////////////////////////////////////////////////////////////////////

        if (pthread_create(&pDevItem->m_level2ReceiveThread,
                           NULL,
                           deviceLevel2ReceiveThread,
                           pDevItem)) {
            syslog(LOG_CRIT,
                   "%s: Unable to run the device Level II read worker thread.",
                   pDevItem->m_strName.c_str());
            pDevItem->m_bQuit = true;
            pthread_join(pDevItem->m_level2WriteThread, NULL);
            dlclose(hdll);
            return NULL; // TODO close dll, kill other thread
        }

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level II Write thread created.",
                   pDevItem->m_strName.c_str());
        }

        // Just sit and wait until the end of the world as we know it...
        while (!pDevItem->m_bQuit) {
            sleep(1);
        }

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level II Closing.",
                   pDevItem->m_strName.c_str());
        }

        // Close channel
        pDevItem->m_proc_VSCPClose(pDevItem->m_openHandle);

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level II Closed.",
                   pDevItem->m_strName.c_str());
        }

    level2_driver_exit:

        pDevItem->m_bQuit = true;
        pthread_join(pDevItem->m_level2WriteThread, NULL);
        pthread_join(pDevItem->m_level2ReceiveThread, NULL);

        // Unload dll
        dlclose(hdll);

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level II Done waiting for threads.",
                   pDevItem->m_strName.c_str());
        }

    } else if (VSCP_DRIVER_LEVEL3 == pDevItem->m_driverLevel) {

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level III Start server loop.",
                   pDevItem->m_strName.c_str());
        }

        // Just sit and wait until the end of the world as we know it...
        while (!pDevItem->m_bQuit) {
            sleep(1);
        }

        if (pCtrlObj->m_debugFlags[0] & VSCP_DEBUG1_DRIVER) {
            syslog(LOG_DEBUG,
                   "%s: [Device tread] Level II End server loop.",
                   pDevItem->m_strName.c_str());
        }
    }

    // Remove messages in the client queues
    pthread_mutex_lock(&pCtrlObj->m_clientList.m_mutexItemList);
    pCtrlObj->removeClient(pClientItem);
    pthread_mutex_unlock(&pCtrlObj->m_clientList.m_mutexItemList);

    return NULL;
}
예제 #5
0
파일: canalconfobj.cpp 프로젝트: ajje/vscp
void WizardPageCanalConfig::CreateControls()
{
    WizardPageCanalConfig* itemWizardPage = this;

    wxBoxSizer* itemBoxSizer = new wxBoxSizer( wxVERTICAL );
    itemWizardPage->SetSizer( itemBoxSizer );

    wxStaticText* itemStaticTextHeader = new wxStaticText;
    itemStaticTextHeader->Create( itemWizardPage,
                                    wxID_STATIC,
                                    m_strHead,
                                    wxDefaultPosition,
                                    wxSize( DEFAULT_STOCK_TEXT_WIDTH, -1 ),
                                    0 );
#if  wxCHECK_VERSION(2, 9, 5)                                    
    itemStaticTextHeader->SetFont( wxFont( wxFontInfo(16).FaceName("Tahoma").Bold() ) );
#else
    itemStaticTextHeader->SetFont( wxFont( 10, wxSWISS, wxNORMAL, wxBOLD, false, wxT( "Tahoma" ) ) );
#endif    
    itemBoxSizer->Add( itemStaticTextHeader, 0, wxALIGN_LEFT | wxALL, 5 );

    wxStaticText* itemStaticTextDescription = new wxStaticText;
    itemStaticTextDescription->Create( itemWizardPage,
                                            wxID_STATIC,
                                            m_pItem->m_description,
                                            wxDefaultPosition,
                                            wxSize( DEFAULT_STOCK_TEXT_WIDTH, -1 ),
                                            0 );
    itemBoxSizer->Add( itemStaticTextDescription, 0, wxALIGN_LEFT | wxALL, 5 );

    if ( m_pItem->m_infourl.Length() ) {

        wxHyperlinkCtrl* intenHyperLink = new wxHyperlinkCtrl;
        intenHyperLink->Create( itemWizardPage,
                                wxID_STATIC,
                                _( "Click for more information" ),
                                m_pItem->m_infourl );
        itemBoxSizer->Add( intenHyperLink, 0, wxALIGN_LEFT | wxALL, 5 );

        itemBoxSizer->Add( 5, 5, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5 );

    }

    itemBoxSizer->Add( 5, 5, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5 );

    if ( type_choice == m_pItem->m_type ) {
        
        wxArrayString wxstrings;
        for ( unsigned int i = 0; i < m_pItem->m_listChoice.GetCount(); i++ ) {
            wxstrings.Add( m_pItem->m_listChoice[ i ]->m_description );
        }

        m_listBox = new wxListBox;
        
        m_listBox->Create( itemWizardPage,
                             m_windowsID++,
                             wxDefaultPosition,
                             wxSize( 370, -1 ),
                             wxstrings );
       
        if ( WizardPageCanalConfig::ShowToolTips() ) {
            m_listBox->SetToolTip( _( "Set value for parameter" ) );
        }
        
        m_listBox->SetBackgroundColour( wxColour( 255, 255, 210 ) );
        unsigned long sel = 0;
        sel = vscp_readStringValue( m_strValue );
        //m_strValue.ToCULongsel( &sel );
        m_listBox->Select( sel );
        itemBoxSizer->Add( m_listBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5 );

    }
    else if ( type_boolean == m_pItem->m_type ) {
        
        m_boolChoice = new wxCheckBox;
        
        m_boolChoice->Create( itemWizardPage,
                                m_windowsID++,
                                _("Value for flag"),
                                wxDefaultPosition,
                                wxSize( 370, -1 ) );
        if ( WizardPageCanalConfig::ShowToolTips() ) {
            m_boolChoice->SetToolTip( _( "Set to enable" ) );
        }

        m_boolChoice->SetBackgroundColour( wxColour( 255, 255, 210 ) );
        if ( m_strValue.IsNumber() ) {
            unsigned long val = 0;
            val = vscp_readStringValue( m_strValue );
            //m_strValue.ToCULong( &val );
            if ( val ) m_boolChoice->SetValue( true );
        }
        else {
            m_strValue.MakeUpper();
            if ( m_strValue.Find( _( "TRUE" ) ) ) {
                m_boolChoice->SetValue( true );
            }
        }

        itemBoxSizer->Add( m_boolChoice, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5 );

    }
    else {

        m_textField = new wxTextCtrl;

        m_textField->Create( itemWizardPage,
                                m_windowsID++,
                                wxEmptyString,
                                wxDefaultPosition,
                                wxSize( 370, -1 ) );

        if ( WizardPageCanalConfig::ShowToolTips() ) {
            m_textField->SetToolTip( _( "Set value for parameter" ) );
        }

        m_textField->SetBackgroundColour( wxColour( 255, 255, 210 ) );
        m_textField->SetValue( m_strValue );
        itemBoxSizer->Add( m_textField, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5 );

    }

    itemBoxSizer->Add( 5, 5, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5 );

}
예제 #6
0
파일: canalconfobj.cpp 프로젝트: ajje/vscp
bool CCanalConfObj::parseDriverInfo( wxString& xmldata )
{
    bool rv = true;
    wxStringInputStream xmlstream( xmldata );
    wxXmlDocument doc;

    // Empty old MDF information
    //clearStorage();

    if ( !doc.Load( xmlstream ) ) {
        return false;
    }

    // start processing the XML file
    if ( doc.GetRoot()->GetName() != wxT( "config" ) ) {
        return false;
    }

    wxXmlNode *child1 = doc.GetRoot()->GetChildren();
    while ( child1 ) {
        if ( child1->GetName() == wxT( "description" ) ) {  
            
            m_decription = child1->GetNodeContent();

            wxString str = child1->GetAttribute( _( "type" ), _( "text" ) );
            str.Trim();
            str.Trim( false );
            str.MakeUpper();

            m_TypeDescription = type_text;
            if ( wxNOT_FOUND != str.Find( _( "HTML" ) ) ) {
                m_TypeDescription = type_html;
            }
        }
        else if ( child1->GetName() == wxT( "level" ) ) {
            m_level = vscp_readStringValue( child1->GetNodeContent() );
        }
        else if ( child1->GetName() == wxT( "blocking" ) ) {

            wxString str = child1->GetNodeContent();
            str.Trim();
            str.Trim( false );
            str.MakeUpper();

            m_bBlocking = true;
            if ( wxNOT_FOUND != str.Find( _( "NO" ) ) ) {
                m_bBlocking = false;
            }
        }
        else if ( child1->GetName() == wxT( "infourl" ) ) {
            m_infourl = child1->GetNodeContent();
        }
        else if ( child1->GetName() == wxT( "items" ) ) {
            
            wxXmlNode *child2 = child1->GetChildren();
            while ( child2 ) {

                if ( child2->GetName() == wxT( "item" ) ) {
                    
                    wxString str;

                    CCanalObj_OneItem *pOneItem = new CCanalObj_OneItem;
                    wxASSERT( NULL != pOneItem );
                    m_listItem.Append( pOneItem );
                    
                    pOneItem->m_pos = vscp_readStringValue( child2->GetAttribute( _( "pos" ), _( "0" ) ) );
                    pOneItem->m_description = child2->GetAttribute( _( "description" ), _( "" ) );
                    pOneItem->m_infourl = child2->GetAttribute( _( "infourl" ), _( "" ) );
                    
                    str = child2->GetAttribute( _( "optional" ), _( "false" ) );
                    str.MakeUpper();
                    pOneItem->m_bOptional = false;
                    if ( wxNOT_FOUND != str.Find( _( "TRUE" ) ) ) {
                        m_bBlocking = true;
                    }

                    pOneItem->m_type = type_unknown;
                    str = child2->GetAttribute( _( "type" ), _( "string" ) );
                    str.MakeUpper();
                    if ( wxNOT_FOUND != str.Find( _( "STRING" ) ) ) {
                        pOneItem->m_type = type_string;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "BOOLEAN" ) ) ) {
                        pOneItem->m_type = type_boolean;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "INT32" ) ) ) {
                        pOneItem->m_type = type_int32;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "UINT32" ) ) ) {
                        pOneItem->m_type = type_uint32;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "FLOAT" ) ) ) {
                        pOneItem->m_type = type_float;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "CHOICE" ) ) ) {
                        pOneItem->m_type = type_choice;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "ISOTIME" ) ) ) {
                        pOneItem->m_type = type_isotime;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "ISODATE" ) ) ) {
                        pOneItem->m_type = type_isodate;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "ISODATETIME" ) ) ) {
                        pOneItem->m_type = type_isodatetime;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "GUID" ) ) ) {
                        pOneItem->m_type = type_guid;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "EVENT" ) ) ) {
                        pOneItem->m_type = type_event;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "FILTER" ) ) ) {
                        pOneItem->m_type = type_filter;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "MASK" ) ) ) {
                        pOneItem->m_type = type_filter;
                    }

                    pOneItem->m_strValue = child2->GetAttribute( _( "value" ), _( "" ) );

                    wxXmlNode *child3 = child2->GetChildren();
                    while ( child3 ) {

                        if ( child3->GetName() == wxT( "choice" ) ) {

                            CCanalObj_Choice *pChoice = new CCanalObj_Choice;
                            wxASSERT( NULL != pChoice );
                            pOneItem->m_listChoice.Append( pChoice );

                            pChoice->m_description = 
                                        child3->GetAttribute( _( "description" ), _( "" ) );
                            pChoice->m_value = child3->GetAttribute( _( "value" ), _( "" ) );

                        } // choice

                        child3 = child3->GetNext();
                    }

                } // item

                child2 = child2->GetNext();
            } // while

        }
        else if ( child1->GetName() == wxT( "flags" ) ) {

            wxXmlNode *child2 = child1->GetChildren();
            while ( child2 ) {

                if ( ( child2->GetName() == wxT( "bit" )  ) || 
                        ( child2->GetName() == wxT( "flag" ) ) ) {

                    wxString str;

                    CCanalObj_FlagBit *pFlagBit = new CCanalObj_FlagBit;
                    wxASSERT( NULL != pFlagBit );
                    m_listFlagBits.Append( pFlagBit );

                    pFlagBit->m_pos = vscp_readStringValue( child2->GetAttribute( _( "pos" ), _( "0" ) ) );
                    pFlagBit->m_width = vscp_readStringValue( child2->GetAttribute( _( "width" ), _( "1" ) ) );
                    pFlagBit->m_defaultVal = vscp_readStringValue( child2->GetAttribute( _( "default" ), _( "0" ) ) );
                    pFlagBit->m_description = child2->GetAttribute( _( "description" ), _( "" ) );
                    pFlagBit->m_infourl = child2->GetAttribute( _( "infourl" ), _( "" ) );

                    pFlagBit->m_type = flagtype_bool;
                    str = child2->GetAttribute( _( "type" ), _( "BOOL" ) );
                    str.MakeUpper();
                    if ( wxNOT_FOUND != str.Find( _( "CHOICE" ) ) ) {
                        pFlagBit->m_type = flagtype_choice;
                    }
                    else if ( wxNOT_FOUND != str.Find( _( "VALUE" ) ) ) {
                        pFlagBit->m_type = flagtype_value;
                    }

                    wxXmlNode *child3 = child2->GetChildren();
                    while ( child3 ) {

                        if ( child3->GetName() == wxT( "choice" ) ) {

                            CCanalObj_Choice *pChoice = new CCanalObj_Choice;
                            wxASSERT( NULL != pChoice );
                            pFlagBit->m_listChoice.Append( pChoice );

                            pChoice->m_description = child3->GetAttribute( _( "description" ), _( "" ) );
                            pChoice->m_value = child3->GetAttribute( _( "value" ), _( "" ) );

                        } // choice

                        child3 = child3->GetNext();
                    }

                }
       
                child2 = child2->GetNext();
            }

        }

        child1 = child1->GetNext();
    }

    return rv;
}
예제 #7
0
void frmScanforDevices::OnButtonScanClick(wxCommandEvent& event)
{
    bool bSlowAlgorithm = false;
    uint8_t val;
    uint8_t reg[256];
    CMDF mdf;
    wxString url;
    wxTreeItemId newitem;

    wxBusyCursor wait;
    
    bSlowAlgorithm = m_slowAlgorithm->GetValue();
    
    uint8_t scanFrom = vscp_readStringValue(m_ctrlEditFrom->GetValue());
    uint8_t scanTo = vscp_readStringValue(m_ctrlEditTo->GetValue());
    
    if ( scanFrom >=  scanTo ) {
        wxMessageBox(_("Node to scan from must be less then to"));
        return;
    }

    m_DeviceTree->DeleteAllItems();
    m_htmlWnd->SetPage( "<html><body></body></html>" );
    m_htmlWnd->Update();

    wxProgressDialog progressDlg(_("Scanning for VSCP devices"),
            _("Reading Registers"),
            2*(scanTo-scanFrom+1),
            this,
            wxPD_ELAPSED_TIME | wxPD_AUTO_HIDE  | wxPD_CAN_ABORT);

    wxTreeItemId rootItem = m_DeviceTree->AddRoot(_("Found device(s)"));
    m_DeviceTree->ExpandAll();

    // Fetch GUID for the interface
	if ( USE_TCPIP_INTERFACE == m_csw.getDeviceType() ) {
		fetchIterfaceGUID();
	}

    if ( bSlowAlgorithm ) {

        for ( int i = scanFrom; i <= scanTo; i++ ) {

            if (!progressDlg.Update(i, wxString::Format(_("Checking for device %d"), i))) {
                if (m_DeviceTree->GetCount()) {
                    wxTreeItemIdValue cookie;
                    wxTreeItemId item = m_DeviceTree->GetFirstChild(m_DeviceTree->GetRootItem(), cookie);
                    if ( item.IsOk() ) m_DeviceTree->SelectItem( item );
                }
                ::wxEndBusyCursor();
                break;
            }

            if ( USE_DLL_INTERFACE == m_csw.getDeviceType() ) {

                // Empty input queue
                canalMsg canalmsg;
                while ( m_csw.getDllInterface()->doCmdDataAvailable() ) {
                    if ( CANAL_ERROR_SUCCESS != m_csw.getDllInterface()->doCmdReceive( &canalmsg ) ) break;
                }

                if ( CANAL_ERROR_SUCCESS == 
                    m_csw.getDllInterface()->readLevel1Register( i, 0, 0xd0, &val ) ) {

                    newitem = m_DeviceTree->AppendItem(rootItem, wxString::Format(_("Node with nickname=%d"), i));
                    m_DeviceTree->ExpandAll();
                    memset(reg, 0, sizeof(reg));

                    scanElement *pElement = new scanElement;
                    if (NULL != pElement) {
                        pElement->m_bLoaded = false;
                        pElement->m_nodeid = i;
                        //pElement->m_html = str; 
                        memset(pElement->m_reg, 0, 256);
                        m_DeviceTree->SetItemData(newitem, pElement);
                    }
                }

            } 
            else if (USE_TCPIP_INTERFACE == m_csw.getDeviceType()) {

                cguid destguid;
                destguid = m_ifguid;
                destguid.setLSB(i);

                // Empty input queue
                m_csw.getTcpIpInterface()->doCmdClear();

                if ( CANAL_ERROR_SUCCESS ==  
                    m_csw.getTcpIpInterface()->readLevel2Register( 0xd0,
                                                                    0,
                                                                    &val,
                                                                    m_ifguid,
                                                                    &destguid ) ) {

                    newitem = m_DeviceTree->AppendItem(rootItem, wxString::Format(_("Node with nickname=%d"), i));
                    m_DeviceTree->ExpandAll();
                    
                    scanElement *pElement = new scanElement;
                    if (NULL != pElement) {
                        pElement->m_bLoaded = false;
                        pElement->m_nodeid = i;
                        //pElement->m_html = str; 
                        memset(pElement->m_reg, 0, 256);
                        m_DeviceTree->SetItemData(newitem, pElement);
                    }
                     
                }

            }

            ::wxSafeYield();

        } // for
    }
    else { // Fast Algorithm

        vscpEventEx eventex;

		if (USE_DLL_INTERFACE == m_csw.getDeviceType()) {

            // Empty input queue
            canalMsg canalmsg;
            while ( m_csw.getDllInterface()->doCmdDataAvailable() ) {
                if ( CANAL_ERROR_SUCCESS != m_csw.getDllInterface()->doCmdReceive( &canalmsg ) ) break;
            }

			// Send read register to all nodes.
			for ( int i = scanFrom; i <= scanTo; i++ ) {

#ifdef WIN32				
				progressDlg.Update(i, wxString::Format(_("Checking for device %d"), i));
#endif				

				eventex.vscp_class = VSCP_CLASS1_PROTOCOL;
				eventex.vscp_type = VSCP_TYPE_PROTOCOL_READ_REGISTER;
				eventex.sizeData = 2;		// nodeid + register to read
				eventex.data[ 0 ] = i;		// nodeid
				eventex.data[ 1 ] = 0xd0;	// Register to read
				m_csw.doCmdSend( &eventex );
                wxMilliSleep( 20 );

			}


			// Check for replies
			wxLongLong resendTime = ::wxGetLocalTimeMillis();
       
			std::list<int> found_list;
			bool bLevel2 = false;
			uint8_t cnt = 0; 
			while (true) {
            
				progressDlg.Pulse( wxString::Format(_("Found %d"), found_list.size()));

				while ( m_csw.doCmdDataAvailable() ) {           // Message available

					if ( CANAL_ERROR_SUCCESS == m_csw.doCmdReceive( &eventex ) ) { // Valid event                
#if 0                    
							{
                                wxString str;
                                str = wxString::Format(_("Received Event: class=%d type=%d size=%d data= "), 
                                                            eventex.vscp_class, 
                                                            eventex.vscp_type, 
                                                            eventex.sizeData );
                                for ( int ii = 0; ii < eventex.sizeData; ii++ ) {
                                    str += wxString::Format(_("%02X "), eventex.data[ii] );
                                }
								wxLogDebug(str);
							}
#endif                    
							// Level I Read reply?
							if ( ( VSCP_CLASS1_PROTOCOL == eventex.vscp_class ) &&
									( VSCP_TYPE_PROTOCOL_RW_RESPONSE == eventex.vscp_type ) ) {
								if ( 0xd0 == eventex.data[ 0 ] ) { // Requested register?
									// Add nickname to list 
									found_list.push_back( eventex.GUID[15] );
								}
							}

						} // valid event

					} // Event is available

					if ((::wxGetLocalTimeMillis() - resendTime) > 3000 ) {

						// Take away duplicates
						found_list.unique();
                
						wxTreeItemId newitem;
						for( std::list<int>::iterator list_iter = found_list.begin(); 
							    list_iter != found_list.end(); list_iter++) {
                    
							newitem = m_DeviceTree->AppendItem(rootItem, wxString::Format(_("Node with nickname=%d"), *list_iter));
							m_DeviceTree->ExpandAll();
                    
							scanElement *pElement = new scanElement;
							if (NULL != pElement) {
								pElement->m_bLoaded = false;
								pElement->m_nodeid = *list_iter;
								pElement->m_html = _("Right click on item to load info about node."); 
								memset(pElement->m_reg, 0, 256);
								m_DeviceTree->SetItemData(newitem, pElement);
							}
						}
						break;

					}

			} // while

		
		} // TCP/IP
		else if (USE_TCPIP_INTERFACE == m_csw.getDeviceType()) {

            // Empty input queue
            m_csw.getTcpIpInterface()->doCmdClear();
           
			// Read register at all nodes.
			for ( int i=scanFrom; i<=scanTo; i++ ) {
            
				cguid destguid;
				destguid.setLSB(i);
                
				eventex.head = VSCP_PRIORITY_NORMAL;
				eventex.timestamp = 0;
				eventex.obid = 0;
                
				// Check if a specific interface is used
				if ( !m_ifguid.isNULL() ) {

					progressDlg.Update(i, wxString::Format(_("Checking for device %d"), i));

					eventex.vscp_class = VSCP_CLASS2_LEVEL1_PROTOCOL;
					eventex.vscp_type = VSCP_TYPE_PROTOCOL_READ_REGISTER;

					memset(eventex.GUID, 0, 16);// We use GUID for interface 
					eventex.sizeData = 16 + 2;  // Interface GUID + nodeid + register to read

					m_ifguid.writeGUID(eventex.data);

					eventex.data[ 16 ] = i;     // nodeid
					eventex.data[ 17 ] = 0xd0;  // Register to read

					m_csw.doCmdSend( &eventex );
                    wxMilliSleep( 10 );

				}
                else {
                    wxMessageBox( _("No interface specified. Please select one") );   
                    goto error;
                }
			
			} // for
                

			// Check for replies
			wxLongLong resendTime = ::wxGetLocalTimeMillis();
       
			std::list<int> found_list;
			bool bLevel2 = false;
			uint8_t cnt = 0; 
			while (true) {
            
				progressDlg.Pulse( wxString::Format(_("Found %d"), found_list.size()));

                while ( m_csw.doCmdDataAvailable() ) {      // Message available

					if ( CANAL_ERROR_SUCCESS == m_csw.doCmdReceive( &eventex ) ) { // Valid event
                    
#if 0                    
							{
							wxString str;
								str = wxString::Format(_("Received Event: class=%d type=%d size=%d data=%d %d"), 
									eventex.vscp_class, eventex.vscp_type, eventex.sizeData, eventex.data[15], eventex.data[16] );
								wxLogDebug(str);
							}
#endif                    

						// Level I Read reply?
						if ( ( VSCP_CLASS1_PROTOCOL == eventex.vscp_class ) &&
								(VSCP_TYPE_PROTOCOL_RW_RESPONSE == eventex.vscp_type)) {
							if (eventex.data[ 0 ] == 0xd0) { // Requested register?
								// Add nickname to list 
								found_list.push_back( eventex.GUID[ 15 ] );
							} // Check for correct node
						}                        // Level II 512 Read reply?
						else if (/*!m_ifguid.isNULL() && !bLevel2 &&*/
								(VSCP_CLASS2_LEVEL1_PROTOCOL == eventex.vscp_class) &&
							(VSCP_TYPE_PROTOCOL_RW_RESPONSE == eventex.vscp_type)) {

							//if ( pdestGUID->isSameGUID( event.GUID ) ) {
							// Reg we requested?
							if (0xd0 == eventex.data[ 16 ] ) {
                            
								// Add nickname to list 
								found_list.push_back( eventex.GUID[ 15 ] );
							}
							//}

						}                        // Level II Read reply?
						else if (m_ifguid.isNULL() && bLevel2 &&
								(VSCP_CLASS2_PROTOCOL == eventex.vscp_class) &&
								(VSCP2_TYPE_PROTOCOL_READ_WRITE_RESPONSE == 
							eventex.vscp_type)) {

							// from us
							uint32_t retreg = (eventex.data[ 0 ] << 24) +
												(eventex.data[ 1 ] << 16) +
												(eventex.data[ 2 ] << 8) +
												eventex.data[ 3 ];

							// Register we requested?
							if (retreg == 0xffffffd0) {
								// Add nickname to list 
								found_list.push_back( eventex.data[ 15 ] );
							}
						}

					} // valid event

				} //Event is available

				if ((::wxGetLocalTimeMillis() - resendTime) > 3000 ) {

					// Take away duplicates
					found_list.unique();
                
					wxTreeItemId newitem;
					for ( std::list<int>::iterator list_iter = found_list.begin(); 
							list_iter != found_list.end(); list_iter++) {
                    
						newitem = m_DeviceTree->AppendItem(rootItem, wxString::Format(_("Node with nickname=%d"), *list_iter));
						m_DeviceTree->ExpandAll();
                    
						scanElement *pElement = new scanElement;
						if (NULL != pElement) {
							pElement->m_bLoaded = false;
							pElement->m_nodeid = *list_iter;
							pElement->m_html = _("Right click on item to load info about node. Double click to open configuration window."); 
							memset(pElement->m_reg, 0, 256);
							m_DeviceTree->SetItemData( newitem, pElement );
						}
					}
					break;
            
				} // while
        
			}
        
		} // TCP/IP i/f     
		    
        
    }  // fast

    if ( m_DeviceTree->GetCount() ) {
        m_DeviceTree->SelectItem( m_DeviceTree->GetRootItem() );
    }

error:

    Raise();
    event.Skip(false);
   
}
예제 #8
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

            }
예제 #9
0
bool
CRawEthernet::open(const char *pUsername,
                    const char *pPassword,
                    const char *pHost,
                    short port,
                    const char *pPrefix,
                    const char *pConfig)
{
	bool rv = true;
	wxString wxstr = wxString::FromAscii(pConfig);

	m_username = wxString::FromAscii(pUsername);
	m_password = wxString::FromAscii(pPassword);
	m_host = wxString::FromAscii(pHost);
	m_port = port;
	m_prefix = wxString::FromAscii(pPrefix);

	// Parse the configuration string. It should
	// have the following form
	// path
	// 
	wxStringTokenizer tkz(wxString::FromAscii(pConfig), _(";\n"));

	// Look for rawethernet interface in configuration string
	if (tkz.HasMoreTokens()) {
		// Interface
		m_interface = tkz.GetNextToken();
	}

	// Local Mac
	wxString localMac;
	if (tkz.HasMoreTokens()) {
		localMac = tkz.GetNextToken();
		localMac.MakeUpper();
		wxStringTokenizer tkzmac(localMac, _(":\n"));
		for (int i = 0; i < 6; i++) {
			if (!tkzmac.HasMoreTokens()) break;
			wxString str = _("0X") + tkzmac.GetNextToken();
			m_localMac[ i ] = vscp_readStringValue(str);
			m_localGUIDtx.setAt((9 + i), m_localMac[ i ]);
			m_localGUIDrx.setAt((9 + i), m_localMac[ i ]);
		}
	}


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

	if ( VSCP_ERROR_SUCCESS !=  m_srv.doCmdOpen( m_host,
                                                    m_username,
                                                    m_password ) ) {
		syslog(LOG_ERR,
				"%s",
				(const char *) "Unable to connect to VSCP TCP/IP interface. Terminating!");
		return false;
	}

	// Find the channel id
	uint32_t ChannelID;
	m_srv.doCmdGetChannelID(&ChannelID);

	// The server should hold configuration data for each sensor
	// we want to monitor.
	// 
	// We look for 
	//
	//	 _interface - The ethernet interface to use. Typically this 
	//					is “eth0, eth0, eth1...
	//
	//   _localmac - The MAC address for our outgoing frames.
	//					Typically on the form 00:26:55:CA:1F:DA
	//
	//   _filter - Standard VSCP filter in string form. 
	//				   1,0x0000,0x0006,
	//				   ff:ff:ff:ff:ff:ff:ff:01:00:00:00:00:00:00:00:00
	//				as priority,class,type,GUID
	//				Used to filter what events that is received from 
	//				the socketcan interface. If not give all events 
	//				are received.
	//	 _mask - Standard VSCP mask in string form.
	//				   1,0x0000,0x0006,
	//				   ff:ff:ff:ff:ff:ff:ff:01:00:00:00:00:00:00:00:00
	//				as priority,class,type,GUID
	//				Used to filter what events that is received from 
	//				the socketcan interface. If not give all events 
	//				are received. 
	//

	wxString str;
	wxString strName = m_prefix +
			wxString::FromAscii("_interface");
	m_srv.getVariableString(strName, &m_interface);

	// Local Mac
	if (tkz.HasMoreTokens()) {
		localMac = tkz.GetNextToken();
		localMac.MakeUpper();
		wxStringTokenizer tkzmac(localMac, _(":\n"));
		for (int i = 0; i < 6; i++) {
			if (!tkzmac.HasMoreTokens()) break;
			wxString str = _("0X") + tkzmac.GetNextToken();
			m_localMac[ i ] = vscp_readStringValue(str);
			m_localGUIDtx.setAt((9 + i), m_localMac[ i ]);
			m_localGUIDrx.setAt((9 + i), m_localMac[ i ]);
		}
	}

	strName = m_prefix +
			wxString::FromAscii("_filter");
	if (VSCP_ERROR_SUCCESS ==  m_srv.getVariableString(strName, &str)) {
		vscp_readFilterFromString(&m_vscpfilter, str);
	}

	strName = m_prefix +
			wxString::FromAscii("_mask");
	if (VSCP_ERROR_SUCCESS == m_srv.getVariableString(strName, &str)) {
		vscp_readMaskFromString(&m_vscpfilter, str);
	}

	// start the read workerthread
	m_preadWorkThread = new CWrkReadThread();
	if (NULL != m_preadWorkThread) {
		m_preadWorkThread->m_pObj = this;
		m_preadWorkThread->Create();
		m_preadWorkThread->Run();
	} else {
		rv = false;
	}

	// start the write workerthread
	m_pwriteWorkThread = new CWrkWriteThread();
	if (NULL != m_pwriteWorkThread) {
		m_pwriteWorkThread->m_pObj = this;
		m_pwriteWorkThread->Create();
		m_pwriteWorkThread->Run();
	} else {
		rv = false;
	}

	// Close the channel
	m_srv.doCmdClose();

	return rv;
}
void dlgVscpInterfaceSettings::OnButtonVscpSetConfigurationClick( wxCommandEvent& event )
{
    CDllWrapper dll;
    CCanalConfObj conf;
    foundMetods meth;
    wxString strDrvInfo;
    wxString path = m_PathToDriver->GetValue();

    if ( 0 == path.Length() ) {
        wxMessageBox( _( "Must have a valid path to the driver." ) );
        return;
    }

    // Check that the file exists
    if ( !( ::wxFileExists( path ) ) ) {
        wxMessageBox( _( "The path does not point to a valid file." ) );
        return;
    }

    if ( CANAL_ERROR_SUCCESS != dll.loadGetDriverInfo( path, strDrvInfo, &meth ) ) {
        wxMessageBox( _( "Sorry! This driver does not appears to have a stored description of how it should be configurated. Ask the driver maker to include one!" ) );
        return;
    }

    char buf[ 256000 ];
    wxCharBuffer wxbuf = strDrvInfo.ToUTF8();

    int baselen = strlen( wxbuf.data() );
    int len = ns_base64_decode( (const unsigned char *)wxbuf.data(), baselen, buf );
	
    if ( len != baselen ) {
        wxMessageBox( _( "The configurationd ata was either in the wrong form (should have been base64 encoded xml) or it was absent." ) );
        return;
    }

    // OK we have valid data - Parse it
    wxString driverinfo = wxString::FromUTF8( buf );
    if ( !conf.parseDriverInfo( driverinfo ) ) {
        wxMessageBox( _( "Failed to parse the configuration data." ) );
        return;
    }

    // Start the wizard
    wxString resultConfString;
    wxString str = m_DriverConfigurationString->GetValue();
    uint32_t resultFlags = 0;
    if ( !conf.runWizard( this,
                            str,
                            vscp_readStringValue( m_DriverFlags->GetValue() ),
                            resultConfString, 
                            &resultFlags ) ) {
        wxMessageBox( _( "Failed to run configuration wizard." ) );
        return;
    }

    m_DriverConfigurationString->SetValue( resultConfString );
    wxString strWrk = wxString::Format( _( "%lu" ), resultFlags );
    m_DriverFlags->SetValue( strWrk );

	event.Skip(); 
}