bool CVariableStorage::save( wxString& path ) { CVSCPVariable *pVariable; wxString str; #ifdef BUILD_VSCPD_SERVICE wxStandardPaths stdPath; // Set the default variable configuration path m_configPath = stdPath.GetConfigDir(); m_configPath += _("/vscp/variable.xml"); #endif wxFFileOutputStream *pFileStream = new wxFFileOutputStream( path ); if ( NULL == pFileStream ) return false; pFileStream->Write("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n\n", strlen("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n\n") ); // VSCP variables pFileStream->Write("<persistent>\n\n", strlen("<persistent>\n\n") ); listVscpVariable::iterator it; for( it = m_listVariable.begin(); it != m_listVariable.end(); ++it ) { if ( NULL == ( pVariable = *it ) ) continue; wxString name = pVariable->getName(); if ( ( NULL != pVariable ) && pVariable->isPersistent() ) { switch ( pVariable->getType() ) { case VSCP_DAEMON_VARIABLE_CODE_VSCP_EVENT: str.Printf( _(" <variable type=\"event\">\n"), pVariable->getType() ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); //pFileStream->Write( pVariable->m_strValue, pVariable->m_strValue.Length() ); pVariable->writeVariableToString( str ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_STRING: str.Printf( _(" <variable type=\"string\">\n"), pVariable->getType() ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); pFileStream->Write( pVariable->m_strValue.mb_str(), strlen( pVariable->m_strValue.mb_str() ) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_BOOLEAN: str.Printf( _(" <variable type=\"bool\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); if ( pVariable->m_boolValue ) { pFileStream->Write( "true", strlen("true") ); } else { pFileStream->Write( "false", strlen("false") ); } pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_INTEGER: str.Printf( _(" <variable type=\"integer\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); str.Printf( _("%d"), pVariable->m_longValue ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_LONG: str.Printf( _(" <variable type=\"long\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); str.Printf( _("%d"), pVariable->m_longValue ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_DOUBLE: str.Printf( _(" <variable type=\"double\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); str.Printf( _("%f"), pVariable->m_floatValue ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_VSCP_MEASUREMENT: str.Printf( _(" <variable type=\"measurement\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); //writeVscpDataWithSizeToString( pVariable->m_normIntSize, // pVariable->m_normInteger, // str, // true ); //pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pVariable->writeVariableToString( str ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_VSCP_EVENT_DATA: str.Printf( _(" <variable type=\"data\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); pVariable->writeVariableToString( str ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_VSCP_EVENT_CLASS: str.Printf( _(" <variable type=\"class\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); str.Printf( _("%d"), pVariable->m_event.vscp_class ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_VSCP_EVENT_TYPE: str.Printf( _(" <variable type=\"type\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); str.Printf( _("%d"), pVariable->m_event.vscp_type ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_VSCP_EVENT_TIMESTAMP: str.Printf( _(" <variable type=\"timestamp\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); //str.Printf( _("%d"), pVariable->m_event.timestamp ); //pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pVariable->writeVariableToString( str ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_VSCP_EVENT_GUID: str.Printf( _(" <variable type=\"guid\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); pVariable->writeVariableToString( str ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; case VSCP_DAEMON_VARIABLE_CODE_DATETIME: str.Printf( _(" <variable type=\"datetime\">\n") ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); writeGuidToString( &pVariable->m_event, str ); // Write name pFileStream->Write( " <name>", strlen(" <name>") ); str = pVariable->getName(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</name>\n", strlen("</name>\n") ); // Write note pFileStream->Write( " <note>", strlen(" <note>") ); str = pVariable->getNote(); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</note>\n", strlen("</note>\n") ); // Write value pFileStream->Write( " <value>", strlen(" <value>") ); //pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); //str = pVariable->m_timestamp.FormatISODate(); //str += _(" "); //str = pVariable->m_timestamp.FormatISOTime(); pVariable->writeVariableToString( str ); pFileStream->Write( str.mb_str(), strlen(str.mb_str()) ); pFileStream->Write( "</value>\n", strlen("</value>\n") ); pFileStream->Write( " </variable>\n\n", strlen(" </variable>\n\n") ); break; } } } // DM matrix information end pFileStream->Write("</persistent>\n",strlen("</persistent>\n")); // Close the file pFileStream->Close(); return true; }
void *deviceThread::Entry() { // Must have a valid pointer to the device item if (NULL == m_pDeviceItem) return NULL; // 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 m_pDeviceItem->m_pClientItem = new CClientItem; if (NULL == m_pDeviceItem->m_pClientItem) { return NULL; } // This is now an active Client m_pDeviceItem->m_pClientItem->m_bOpen = true; if ( VSCP_DRIVER_LEVEL2 == m_pDeviceItem->m_driverLevel ) { m_pDeviceItem->m_pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_DRIVER_LEVEL2; } else { m_pDeviceItem->m_pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_DRIVER_LEVEL1; } m_pDeviceItem->m_pClientItem->m_strDeviceName = m_pDeviceItem->m_strName; m_pDeviceItem->m_pClientItem->m_strDeviceName += _(" Started at "); wxDateTime now = wxDateTime::Now(); m_pDeviceItem->m_pClientItem->m_strDeviceName += now.FormatISODate(); m_pDeviceItem->m_pClientItem->m_strDeviceName += _(" "); m_pDeviceItem->m_pClientItem->m_strDeviceName += now.FormatISOTime(); m_pCtrlObject->logMsg(m_pDeviceItem->m_pClientItem->m_strDeviceName + _("\n"), DAEMON_LOGMSG_DEBUG); // Add the client to the Client List m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->addClient(m_pDeviceItem->m_pClientItem); m_pCtrlObject->m_wxClientMutex.Unlock(); // Load dynamic library if (!m_wxdll.Load(m_pDeviceItem->m_strPath, wxDL_LAZY)) { m_pCtrlObject->logMsg(_("Unable to load dynamic library.\n") ); return NULL; } if (VSCP_DRIVER_LEVEL1 == m_pDeviceItem->m_driverLevel) { // Now find methods in library { wxString str; str = _("Loading level I driver: "); str += m_pDeviceItem->m_strName; str += _("\n"); m_pCtrlObject->logMsg(str); wxLogDebug(str); } // * * * * CANAL OPEN * * * * if (NULL == (m_pDeviceItem->m_proc_CanalOpen = (LPFNDLL_CANALOPEN) m_wxdll.GetSymbol(_T("CanalOpen")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalOpen.\n") ); return NULL; } // * * * * CANAL CLOSE * * * * if (NULL == (m_pDeviceItem->m_proc_CanalClose = (LPFNDLL_CANALCLOSE) m_wxdll.GetSymbol(_T("CanalClose")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalClose.\n") ); return NULL; } // * * * * CANAL GETLEVEL * * * * if (NULL == (m_pDeviceItem->m_proc_CanalGetLevel = (LPFNDLL_CANALGETLEVEL) m_wxdll.GetSymbol(_T("CanalGetLevel")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalGetLevel.\n") ); return NULL; } // * * * * CANAL SEND * * * * if (NULL == (m_pDeviceItem->m_proc_CanalSend = (LPFNDLL_CANALSEND) m_wxdll.GetSymbol(_T("CanalSend")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalSend.\n") ); return NULL; } // * * * * CANAL DATA AVAILABLE * * * * if (NULL == (m_pDeviceItem->m_proc_CanalDataAvailable = (LPFNDLL_CANALDATAAVAILABLE) m_wxdll.GetSymbol(_T("CanalDataAvailable")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalDataAvailable.\n") ); return NULL; } // * * * * CANAL RECEIVE * * * * if (NULL == (m_pDeviceItem->m_proc_CanalReceive = (LPFNDLL_CANALRECEIVE) m_wxdll.GetSymbol(_T("CanalReceive")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalReceive.\n") ); return NULL; } // * * * * CANAL GET STATUS * * * * if (NULL == (m_pDeviceItem->m_proc_CanalGetStatus = (LPFNDLL_CANALGETSTATUS) m_wxdll.GetSymbol(_T("CanalGetStatus")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalGetStatus.\n") ); return NULL; } // * * * * CANAL GET STATISTICS * * * * if (NULL == (m_pDeviceItem->m_proc_CanalGetStatistics = (LPFNDLL_CANALGETSTATISTICS) m_wxdll.GetSymbol(_T("CanalGetStatistics")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalGetStatistics.\n") ); return NULL; } // * * * * CANAL SET FILTER * * * * if (NULL == (m_pDeviceItem->m_proc_CanalSetFilter = (LPFNDLL_CANALSETFILTER) m_wxdll.GetSymbol(_T("CanalSetFilter")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalSetFilter.\n") ); return NULL; } // * * * * CANAL SET MASK * * * * if (NULL == (m_pDeviceItem->m_proc_CanalSetMask = (LPFNDLL_CANALSETMASK) m_wxdll.GetSymbol(_T("CanalSetMask")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalSetMask.\n") ); return NULL; } // * * * * CANAL GET VERSION * * * * if (NULL == (m_pDeviceItem->m_proc_CanalGetVersion = (LPFNDLL_CANALGETVERSION) m_wxdll.GetSymbol(_T("CanalGetVersion")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalGetVersion.\n") ); return NULL; } // * * * * CANAL GET DLL VERSION * * * * if (NULL == (m_pDeviceItem->m_proc_CanalGetDllVersion = (LPFNDLL_CANALGETDLLVERSION) m_wxdll.GetSymbol(_T("CanalGetDllVersion")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalGetDllVersion.\n") ); return NULL; } // * * * * CANAL GET VENDOR STRING * * * * if (NULL == (m_pDeviceItem->m_proc_CanalGetVendorString = (LPFNDLL_CANALGETVENDORSTRING) m_wxdll.GetSymbol(_T("CanalGetVendorString")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalGetVendorString.\n") ); return NULL; } // ****************************** // Generation 2 Methods // ****************************** // * * * * CANAL BLOCKING SEND * * * * m_pDeviceItem->m_proc_CanalBlockingSend = NULL; if (m_wxdll.HasSymbol(_T("CanalBlockingSend"))) { if (NULL == (m_pDeviceItem->m_proc_CanalBlockingSend = (LPFNDLL_CANALBLOCKINGSEND) m_wxdll.GetSymbol(_T("CanalBlockingSend")))) { m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalBlockingSend. Probably Generation 1 driver.\n") ); m_pDeviceItem->m_proc_CanalBlockingSend = NULL; } } else { m_pCtrlObject->logMsg(_T("CanalBlockingSend not available. \n\tNon blocking operations set.\n") ); } // * * * * CANAL BLOCKING RECEIVE * * * * m_pDeviceItem->m_proc_CanalBlockingReceive = NULL; if (m_wxdll.HasSymbol(_T("CanalBlockingReceive"))) { if (NULL == (m_pDeviceItem->m_proc_CanalBlockingReceive = (LPFNDLL_CANALBLOCKINGRECEIVE) m_wxdll.GetSymbol(_T("CanalBlockingReceive")))) { m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalBlockingReceive. Probably Generation 1 driver.\n") ); m_pDeviceItem->m_proc_CanalBlockingReceive = NULL; } } else { m_pCtrlObject->logMsg(_T("CanalBlockingReceive not available. \n\tNon blocking operations set.\n")); } // * * * * CANAL GET DRIVER INFO * * * * m_pDeviceItem->m_proc_CanalGetdriverInfo = NULL; if (m_wxdll.HasSymbol(_T("CanalGetDriverInfo"))) { if (NULL == (m_pDeviceItem->m_proc_CanalGetdriverInfo = (LPFNDLL_CANALGETDRIVERINFO) m_wxdll.GetSymbol(_T("CanalGetDriverInfo")))) { m_pCtrlObject->logMsg(_T("Unable to get dl entry for CanalGetDriverInfo. Probably Generation 1 driver.\n") ); m_pDeviceItem->m_proc_CanalGetdriverInfo = NULL; } } // Open the device m_pDeviceItem->m_openHandle = m_pDeviceItem->m_proc_CanalOpen((const char *) m_pDeviceItem->m_strParameter.mb_str(wxConvUTF8), m_pDeviceItem->m_DeviceFlags); // Check if the driver opened properly if (m_pDeviceItem->m_openHandle <= 0) { wxString errMsg = _T("Failed to open driver. Will not use it! \n\t[ ") + m_pDeviceItem->m_strName + _T(" ]\n"); m_pCtrlObject->logMsg( errMsg ); return NULL; } else { wxString wxstr = wxString::Format(_("Driver %s opended.\n"), (const char *)m_pDeviceItem->m_strName.mbc_str() ); m_pCtrlObject->logMsg( wxstr ); } // Get Driver Level m_pDeviceItem->m_driverLevel = m_pDeviceItem->m_proc_CanalGetLevel(m_pDeviceItem->m_openHandle); // * * * Level I Driver * * * // Check if blocking driver is available if (NULL != m_pDeviceItem->m_proc_CanalBlockingReceive) { // * * * * Blocking version * * * * ///////////////////////////////////////////////////////////////////////////// // Device write worker thread ///////////////////////////////////////////////////////////////////////////// m_pwriteThread = new deviceCanalWriteThread; if (m_pwriteThread) { m_pwriteThread->m_pMainThreadObj = this; wxThreadError err; if (wxTHREAD_NO_ERROR == (err = m_pwriteThread->Create())) { m_pwriteThread->SetPriority(WXTHREAD_MAX_PRIORITY); if (wxTHREAD_NO_ERROR != (err = m_pwriteThread->Run())) { m_pCtrlObject->logMsg(_("Unable to run device write worker thread.\n") ); } } else { m_pCtrlObject->logMsg(_("Unable to create device write worker thread.\n") ); } } else { m_pCtrlObject->logMsg(_("Unable to allocate memory for device write worker thread.\n") ); } ///////////////////////////////////////////////////////////////////////////// // Device read worker thread ///////////////////////////////////////////////////////////////////////////// m_preceiveThread = new deviceCanalReceiveThread; if (m_preceiveThread) { m_preceiveThread->m_pMainThreadObj = this; wxThreadError err; if (wxTHREAD_NO_ERROR == (err = m_preceiveThread->Create())) { m_preceiveThread->SetPriority(WXTHREAD_MAX_PRIORITY); if (wxTHREAD_NO_ERROR != (err = m_preceiveThread->Run())) { m_pCtrlObject->logMsg(_("Unable to run device receive worker thread.\n") ); } } else { m_pCtrlObject->logMsg(_("Unable to create device receive worker thread.\n") ); } } else { m_pCtrlObject->logMsg(_("Unable to allocate memory for device receive worker thread.\n") ); } // Just sit and wait until the end of the world as we know it... while (!m_pDeviceItem->m_bQuit) { wxSleep(1); } m_preceiveThread->m_bQuit = true; m_pwriteThread->m_bQuit = true; m_preceiveThread->Wait(); m_pwriteThread->Wait(); } else { // * * * * Non blocking version * * * * bool bActivity; while (!TestDestroy() && !m_pDeviceItem->m_bQuit) { bActivity = false; ///////////////////////////////////////////////////////////////////////////// // Receive from device // ///////////////////////////////////////////////////////////////////////////// canalMsg msg; if (m_pDeviceItem->m_proc_CanalDataAvailable(m_pDeviceItem->m_openHandle)) { if (CANAL_ERROR_SUCCESS == m_pDeviceItem->m_proc_CanalReceive(m_pDeviceItem->m_openHandle, &msg)) { bActivity = true; // There must be room in the receive queue if (m_pCtrlObject->m_maxItemsInClientReceiveQueue > m_pCtrlObject->m_clientOutputQueue.GetCount()) { vscpEvent *pvscpEvent = new vscpEvent; if (NULL != pvscpEvent) { // Convert CANAL message to VSCP event vscp_convertCanalToEvent( pvscpEvent, &msg, m_pDeviceItem->m_pClientItem->m_guid.m_id ); pvscpEvent->obid = m_pDeviceItem->m_pClientItem->m_clientID; m_pCtrlObject->m_mutexClientOutputQueue.Lock(); m_pCtrlObject->m_clientOutputQueue.Append(pvscpEvent); m_pCtrlObject->m_semClientOutputQueue.Post(); m_pCtrlObject->m_mutexClientOutputQueue.Unlock(); } } } } // data available // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Send messages (if any) in the outqueue // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Check if there is something to send if (m_pDeviceItem->m_pClientItem->m_clientInputQueue.GetCount()) { bActivity = true; CLIENTEVENTLIST::compatibility_iterator nodeClient; m_pDeviceItem->m_pClientItem->m_mutexClientInputQueue.Lock(); nodeClient = m_pDeviceItem->m_pClientItem->m_clientInputQueue.GetFirst(); vscpEvent *pqueueEvent = nodeClient->GetData(); m_pDeviceItem->m_pClientItem->m_mutexClientInputQueue.Unlock(); canalMsg canalMsg; vscp_convertEventToCanal(&canalMsg, pqueueEvent); if (CANAL_ERROR_SUCCESS == m_pDeviceItem->m_proc_CanalSend(m_pDeviceItem->m_openHandle, &canalMsg)) { // Remove the node delete pqueueEvent; m_pDeviceItem->m_pClientItem->m_clientInputQueue.DeleteNode(nodeClient); } else { // Another try //m_pCtrlObject->m_semClientOutputQueue.Post(); vscp_deleteVSCPevent(pqueueEvent); m_pDeviceItem->m_pClientItem->m_clientInputQueue.DeleteNode(nodeClient); } } // events if (!bActivity) { ::wxMilliSleep(100); } bActivity = false; } // while working - non blocking } // if blocking/non blocking // Close CANAL channel m_pDeviceItem->m_proc_CanalClose(m_pDeviceItem->m_openHandle); // Library is unloaded in destructor // Remove messages in the client queues m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->removeClient(m_pDeviceItem->m_pClientItem); m_pCtrlObject->m_wxClientMutex.Unlock(); if (NULL != m_preceiveThread) { m_preceiveThread->Wait(); delete m_preceiveThread; } if (NULL != m_pwriteThread) { m_pwriteThread->Wait(); delete m_pwriteThread; } } else if (VSCP_DRIVER_LEVEL2 == m_pDeviceItem->m_driverLevel) { // Now find methods in library { wxString str; str = _("Loading level II driver: <"); str += m_pDeviceItem->m_strName; str += _(">"); str += _("\n"); m_pCtrlObject->logMsg(str); } // * * * * VSCP OPEN * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPOpen = (LPFNDLL_VSCPOPEN) m_wxdll.GetSymbol(_T("VSCPOpen")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPOpen.\n")); return NULL; } // * * * * VSCP CLOSE * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPClose = (LPFNDLL_VSCPCLOSE) m_wxdll.GetSymbol(_T("VSCPClose")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPClose.\n")); return NULL; } // * * * * VSCP BLOCKINGSEND * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPBlockingSend = (LPFNDLL_VSCPBLOCKINGSEND) m_wxdll.GetSymbol(_T("VSCPBlockingSend")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPBlockingSend.\n")); return NULL; } // * * * * VSCP BLOCKINGRECEIVE * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPBlockingReceive = (LPFNDLL_VSCPBLOCKINGRECEIVE) m_wxdll.GetSymbol(_T("VSCPBlockingReceive")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPBlockingReceive.\n")); return NULL; } // * * * * VSCP GETLEVEL * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPGetLevel = (LPFNDLL_VSCPGETLEVEL) m_wxdll.GetSymbol(_T("VSCPGetLevel")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPGetLevel.\n")); return NULL; } // * * * * VSCP GET DLL VERSION * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPGetDllVersion = (LPFNDLL_VSCPGETDLLVERSION) m_wxdll.GetSymbol(_T("VSCPGetDllVersion")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPGetDllVersion.\n")); return NULL; } // * * * * VSCP GET VENDOR STRING * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPGetVendorString = (LPFNDLL_VSCPGETVENDORSTRING) m_wxdll.GetSymbol(_T("VSCPGetVendorString")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPGetVendorString.\n")); return NULL; } // * * * * VSCP GET DRIVER INFO * * * * if (NULL == (m_pDeviceItem->m_proc_CanalGetdriverInfo = (LPFNDLL_VSCPGETVENDORSTRING) m_wxdll.GetSymbol(_T("VSCPGetDriverInfo")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPGetDriverInfo.\n")); return NULL; } // * * * * VSCP GET WEB PAGE TEMPLATE * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPGetWebPageTemplate = (LPFNDLL_VSCPGETWEBPAGETEMPLATE) m_wxdll.GetSymbol(_T("VSCPGetWebPageTemplate")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPGetWebPageTemplate.\n")); return NULL; } // * * * * VSCP GET WEB PAGE INFO * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPGetWebPageInfo = (LPFNDLL_VSCPGETWEBPAGEINFO) m_wxdll.GetSymbol(_T("VSCPGetWebPageInfo")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPGetWebPageInfo.\n")); return NULL; } // * * * * VSCP WEB PAGE UPDATE * * * * if (NULL == (m_pDeviceItem->m_proc_VSCPWebPageupdate = (LPFNDLL_VSCPWEBPAGEUPDATE) m_wxdll.GetSymbol(_T("VSCPWebPageupdate")))) { // Free the library m_pCtrlObject->logMsg(_T("Unable to get dl entry for VSCPWebPageupdate.\n")); return NULL; } m_pCtrlObject->logMsg(_("Discovered all methods\n")); // Username, password, host and port can be set in configuration file. Read in them here // if they are. wxString strHost(_("127.0.0.1:9598")); wxStringTokenizer tkz(m_pDeviceItem->m_strParameter, _(";")); if (tkz.HasMoreTokens()) { CVSCPVariable *pVar; // Get prefix wxString prefix = tkz.GetNextToken(); // Check if username is specified in the configuration file pVar = m_pCtrlObject->m_VSCP_Variables.find(m_pDeviceItem->m_strName + _("_username")); if (NULL != pVar) { wxString str; if (VSCP_DAEMON_VARIABLE_CODE_STRING == pVar->getType()) { pVar->getValue( str ); m_pCtrlObject->m_driverUsername = str; } } // Check if password is specified in the configuration file pVar = m_pCtrlObject->m_VSCP_Variables.find(m_pDeviceItem->m_strName + _("_password")); if (NULL != pVar) { wxString str; if (VSCP_DAEMON_VARIABLE_CODE_STRING == pVar->getType()) { pVar->getValue( str ); m_pCtrlObject->m_driverPassword = str; } } // Check if host is specified in the configuration file pVar = m_pCtrlObject->m_VSCP_Variables.find(m_pDeviceItem->m_strName + _("_host")); if (NULL != pVar) { wxString str; if (VSCP_DAEMON_VARIABLE_CODE_STRING == pVar->getType()) { pVar->getValue( str ); strHost = str; } } } // Open up the driver m_pDeviceItem->m_openHandle = m_pDeviceItem->m_proc_VSCPOpen( m_pCtrlObject->m_driverUsername.mbc_str(), ( const char * )m_pCtrlObject->m_driverPassword.mbc_str(), ( const char * )strHost.mbc_str(), 0, ( const char * )m_pDeviceItem->m_strName.mbc_str(), ( const char * )m_pDeviceItem->m_strParameter.mbc_str() ); if ( 0 == m_pDeviceItem->m_openHandle ) { // Free the library m_pCtrlObject->logMsg( _T( "Unable to open the library.\n" ) ); return NULL; } ///////////////////////////////////////////////////////////////////////////// // Device write worker thread ///////////////////////////////////////////////////////////////////////////// m_pwriteLevel2Thread = new deviceLevel2WriteThread; if (m_pwriteLevel2Thread) { m_pwriteLevel2Thread->m_pMainThreadObj = this; wxThreadError err; if (wxTHREAD_NO_ERROR == (err = m_pwriteLevel2Thread->Create())) { m_pwriteLevel2Thread->SetPriority(WXTHREAD_MAX_PRIORITY); if (wxTHREAD_NO_ERROR != (err = m_pwriteLevel2Thread->Run())) { m_pCtrlObject->logMsg(_("Unable to run device write worker thread.")); } } else { m_pCtrlObject->logMsg(_("Unable to create device write worker thread.")); } } else { m_pCtrlObject->logMsg(_("Unable to allocate memory for device write worker thread.")); } ///////////////////////////////////////////////////////////////////////////// // Device read worker thread ///////////////////////////////////////////////////////////////////////////// m_preceiveLevel2Thread = new deviceLevel2ReceiveThread; if (m_preceiveLevel2Thread) { m_preceiveLevel2Thread->m_pMainThreadObj = this; wxThreadError err; if (wxTHREAD_NO_ERROR == (err = m_preceiveLevel2Thread->Create())) { m_preceiveLevel2Thread->SetPriority(WXTHREAD_MAX_PRIORITY); if (wxTHREAD_NO_ERROR != (err = m_preceiveLevel2Thread->Run())) { m_pCtrlObject->logMsg(_("Unable to run device receive worker thread.")); } } else { m_pCtrlObject->logMsg(_("Unable to create device receive worker thread.") ); } } else { m_pCtrlObject->logMsg(_("Unable to allocate memory for device receive worker thread.") ); } // Just sit and wait until the end of the world as we know it... while (!TestDestroy() && !m_pDeviceItem->m_bQuit) { wxSleep(200); } m_preceiveLevel2Thread->m_bQuit = true; m_pwriteLevel2Thread->m_bQuit = true; // Close channel m_pDeviceItem->m_proc_VSCPClose(m_pDeviceItem->m_openHandle); // Library is unloaded in destructor // Remove messages in the client queues m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->removeClient(m_pDeviceItem->m_pClientItem); m_pCtrlObject->m_wxClientMutex.Unlock(); if (NULL != m_preceiveLevel2Thread) { m_preceiveLevel2Thread->Wait(); delete m_preceiveLevel2Thread; } if (NULL != m_pwriteLevel2Thread) { m_pwriteLevel2Thread->Wait(); delete m_pwriteLevel2Thread; } } // // ===================================================================================== // return NULL; }
bool CVariableStorage::load( void ) { bool bArray; wxXmlDocument doc; #ifdef BUILD_VSCPD_SERVICE wxStandardPaths stdPath; // Set the default dm configuration path #ifdef WIN32 m_configPath = stdPath.GetConfigDir(); m_configPath += _("/vscp/variables.xml"); #else m_configPath = _("/srv/vscp/variables.xml"); #endif #endif if (!doc.Load( m_configPath ) ) { return false; } //::wxLogDebug ( _("Loading variables from: \n\t") + m_configPath ); // start processing the XML file if ( doc.GetRoot()->GetName() != wxT("persistent") ) { return false; } wxXmlNode *child = doc.GetRoot()->GetChildren(); while (child) { if (child->GetName() == wxT("variable")) { CVSCPVariable *pVar = new CVSCPVariable; pVar->setPersistent( true ); // Loaded variables are persistent bArray = false; // Get variable type - String is default #if wxCHECK_VERSION(3,0,0) pVar->setType( pVar->getVariableTypeFromString( child->GetAttribute( wxT("type"), wxT("string") ) ) ); #else pVar->setType( pVar->getVariableTypeFromString( child->GetPropVal( wxT("type"), wxT("string") ) ) ); #endif wxXmlNode *subchild = child->GetChildren(); while (subchild) { if (subchild->GetName() == wxT("name")) { wxString strName = subchild->GetNodeContent(); strName.Trim(); strName.Trim(false); // Replace spaces in name with underscore int pos; while (wxNOT_FOUND != ( pos = strName.Find(_(" ")))){ strName.SetChar(pos,wxChar('_')); } pVar->setName( strName ); } else if (subchild->GetName() == wxT("value")) { pVar->setValueFromString( pVar->getType(), subchild->GetNodeContent() ); pVar->setPersistatValue( subchild->GetNodeContent() ); } else if (subchild->GetName() == wxT("note")) { pVar->setNote( subchild->GetNodeContent() ); } subchild = subchild->GetNext(); } // Add the variable (always persistent if from file storage) add( pVar ); } child = child->GetNext(); } return true; }