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