AbstractDiagInterface * FreeSSM::initInterface() { // Check if an interface is selected: if (_iface_filename == "") { displayErrorMsg(tr("No interface selected !\n=> Please select a dignostic interface in the preferences.")); return NULL; } // Open interface: AbstractDiagInterface *diagInterface = NULL; if (_iface_type == AbstractDiagInterface::interface_serialPassThrough) { diagInterface = new SerialPassThroughDiagInterface; } else if (_iface_type == AbstractDiagInterface::interface_J2534) { diagInterface = new J2534DiagInterface; } else if (_iface_type == AbstractDiagInterface::interface_ATcommandControlled) { diagInterface = new ATcommandControlledDiagInterface; } else { displayErrorMsg(tr("Internal error:\nThe selected interface type cannot be initialized !\n=> Please report this as a bug.")); return NULL; } if (diagInterface->open(_iface_filename.toStdString())) return diagInterface; // Return error: displayErrorMsg(tr("Couldn't open the diagnostic interface !\nMaybe the device is already in use by another application...")); delete diagInterface; return NULL; }
//! set Current Job Queue File Polling Information QuillErrCode JobQueueDBManager::setJQPollingInfo() { long mtime; long size; ClassAdLogEntry* lcmd; char *sql_str, *tmp; int len; QuillErrCode ret_st; int num_result=0; prober->incrementProbeInfo(); mtime = prober->getLastModifiedTime(); size = prober->getLastSize(); lcmd = caLogParser->getCurCALogEntry(); len = 2048 + strlen(scheddname) + sizeof(lcmd->value); sql_str = (char *)malloc(len * sizeof(char)); snprintf(sql_str, len, "UPDATE JobQueuePollingInfo SET last_file_mtime = %ld, last_file_size = %ld, last_next_cmd_offset = %ld, last_cmd_offset = %ld, last_cmd_type = %d", mtime, size, lcmd->next_offset, lcmd->offset, lcmd->op_type); addJQPollingInfoSQL(sql_str, "last_cmd_key", lcmd->key); addJQPollingInfoSQL(sql_str, "last_cmd_mytype", lcmd->mytype); addJQPollingInfoSQL(sql_str, "last_cmd_targettype", lcmd->targettype); addJQPollingInfoSQL(sql_str, "last_cmd_name", lcmd->name); addJQPollingInfoSQL(sql_str, "last_cmd_value", lcmd->value); len = 50+strlen(scheddname); tmp = (char *) malloc(len); snprintf(tmp, len, " WHERE scheddname = '%s'", scheddname); strcat(sql_str, tmp); ret_st = DBObj->execCommand(sql_str, num_result); if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Update JobQueuePollInfo --- ERROR [SQL] %s\n", sql_str); displayErrorMsg("Update JobQueuePollInfo --- ERROR"); } else if (ret_st == QUILL_SUCCESS && num_result == 0) { // This case is a rare one since the jobqueuepollinginfo // table contains one tuple at all times dprintf(D_ALWAYS, "Update JobQueuePollInfo --- ERROR [SQL] %s\n", sql_str); displayErrorMsg("Update JobQueuePollInfo --- ERROR"); ret_st = QUILL_FAILURE; } free(sql_str); free(tmp); return ret_st; }
/*! process DestroyClassAd command, working with DBMS * Also responsible for writing history records * * Note: Currently we can obtain a 'fairly' accurate view of the history. * 'fairly' because * a) we do miss attributes which the schedd puts in the * history file itself, and the job_queue.log file is unaware of these * attributes. Since our history capturing scheme is via the job_queue.log * file, we miss these attributes. On the UWisc pool, this misses 3 * attributes: LastMatchTime, NumJobMatches, and WantMatchDiagnostics * * b) Also, some jobs do not get into the history tables in the following * rare case: * Quill is unoperational for whatever reason, jobs complete execution and * get deleted from the queue, the job queue log gets truncated, and quill * wakes back up. Since the job queue log is truncated, quill is blissfully * unaware of the jobs that finished while it was not operational. * A possible fix for this is that the schedd should not truncate job logs * when Quill is unoperational, however, we want Quill to be as independent * as possible, and as such, for now, we live with this rare anomaly. * * \param key key * \return the result status * 0: error * 1: success */ QuillErrCode JobQueueDBManager::processDestroyClassAd(char* key) { MyString sql_str1; MyString sql_str2; char cid[100]; char pid[100]; int job_id_type; const char *data_arr[4]; QuillAttrDataType data_typ[4]; // It could be ProcAd or ClusterAd // So need to check job_id_type = getProcClusterIds(key, cid, pid); switch(job_id_type) { case IS_CLUSTER_ID: // ClusterAds sql_str1.formatstr("DELETE FROM ClusterAds_Horizontal WHERE scheddname = '%s' and cluster_id = %s", scheddname, cid); sql_str2.formatstr("DELETE FROM ClusterAds_Vertical WHERE scheddname = '%s' and cluster_id = %s", scheddname, cid); break; case IS_PROC_ID: /* generate SQL to remove the job from job tables */ sql_str1.formatstr("DELETE FROM ProcAds_horizontal WHERE scheddname = '%s' and cluster_id = %s AND proc_id = %s", scheddname, cid, pid); sql_str2.formatstr("DELETE FROM ProcAds_vertical WHERE scheddname = '%s' and cluster_id = %s AND proc_id = %s", scheddname, cid, pid); break; case IS_UNKNOWN_ID: dprintf(D_ALWAYS, "[QUILL++] Destroy ClassAd --- ERROR\n"); return QUILL_FAILURE; // return a error code, 0 break; } { if (DBObj->execCommand(sql_str1.Value()) == QUILL_FAILURE) { displayErrorMsg("Destroy ClassAd Processing --- ERROR"); return QUILL_FAILURE; // return a error code, 0 } if (DBObj->execCommand(sql_str2.Value()) == QUILL_FAILURE) { displayErrorMsg("Destroy ClassAd Processing --- ERROR"); return QUILL_FAILURE; // return a error code, 0 } } return QUILL_SUCCESS; }
/*! delete the job queue related tables * \return the result status * 1: Success * 0: Fail (SQL execution fail) */ QuillErrCode JobQueueDBManager::cleanupJobQueueTables() { const int sqlNum = 4; int i; MyString sql_str[sqlNum]; // we only delete job queue related information. sql_str[0].formatstr( "DELETE FROM clusterads_horizontal WHERE scheddname = '%s'", scheddname); sql_str[1].formatstr( "DELETE FROM clusterads_vertical WHERE scheddname = '%s'", scheddname); sql_str[2].formatstr( "DELETE FROM procads_horizontal WHERE scheddname = '%s'", scheddname); sql_str[3].formatstr( "DELETE FROM procads_vertical WHERE scheddname = '%s'", scheddname); for (i = 0; i < sqlNum; i++) { if (DBObj->execCommand(sql_str[i].Value()) == QUILL_FAILURE) { displayErrorMsg("Clean UP ALL Data --- ERROR"); return QUILL_FAILURE; } } return QUILL_SUCCESS; }
/*! process DeleteAttribute command, working with DBMS * \param key key * \param name attribute name * \return the result status * 0: error * 1: success */ QuillErrCode JobQueueDBManager::processDeleteAttribute(char* key, char* name) { MyString sql_str = ""; char cid[512]; char pid[512]; int job_id_type; QuillErrCode ret_st; QuillAttrDataType attr_type; // It could be ProcAd or ClusterAd // So need to check job_id_type = getProcClusterIds(key, cid, pid); switch(job_id_type) { case IS_CLUSTER_ID: if(isHorizontalClusterAttribute(name, attr_type)) { sql_str.formatstr( "UPDATE ClusterAds_Horizontal SET %s = NULL WHERE scheddname = '%s' and cluster_id = '%s'", name, scheddname, cid); } else { sql_str.formatstr( "DELETE FROM ClusterAds_Vertical WHERE scheddname = '%s' and cluster_id = '%s' AND attr = '%s'", scheddname, cid, name); } break; case IS_PROC_ID: if(isHorizontalProcAttribute(name, attr_type)) { sql_str.formatstr( "UPDATE ProcAds_Horizontal SET %s = NULL WHERE scheddname = '%s' and cluster_id = '%s' AND proc_id = '%s'", name, scheddname, cid, pid); } else { sql_str.formatstr( "DELETE FROM ProcAds_Vertical WHERE scheddname = '%s' and cluster_id = '%s' AND proc_id = '%s' AND attr = '%s'", scheddname, cid, pid, name); } break; case IS_UNKNOWN_ID: dprintf(D_ALWAYS, "Delete Attribute Processing --- ERROR\n"); return QUILL_FAILURE; break; } if (!sql_str.IsEmpty()) { ret_st = DBObj->execCommand(sql_str.Value()); if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Delete Attribute --- ERROR, [SQL] %s\n", sql_str.Value()); displayErrorMsg("Delete Attribute --- ERROR"); return QUILL_FAILURE; } } return QUILL_SUCCESS; }
Script::Script(QObject *parent) : QObject(parent), script_proc(new QProcess(this)) { scriptService = (ScriptService*)parent; clientSettings = ClientSettings::getInstance(); connect(script_proc, SIGNAL(readyReadStandardOutput()), this, SLOT(displayOutputMsg())); connect(script_proc, SIGNAL(readyReadStandardError()), this, SLOT(displayErrorMsg())); connect(script_proc, SIGNAL(started()), this, SLOT(start())); connect(script_proc, SIGNAL(finished(int)), this, SLOT(finish(int))); connect(script_proc, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(handleError(QProcess::ProcessError))); running = false; }
/*! purge all job queue rows and process the entire job_queue.log file * also vacuum the job queue tables */ QuillErrCode JobQueueDBManager::initJobQueueTables() { QuillErrCode st; st = DBObj->beginTransaction(); if(st == QUILL_FAILURE) { displayErrorMsg("JobQueueDBManager::initJobQueueTables: unable to begin a transaction --- ERROR"); return QUILL_FAILURE; } st = cleanupJobQueueTables(); // delete all job queue tables if(st == QUILL_FAILURE) { displayErrorMsg("JobQueueDBManager::initJobQueueTables: unable to clean up job queue tables --- ERROR"); return QUILL_FAILURE; } st = buildAndWriteJobQueue(); // bulk load job queue log // Store polling information in database if (st == QUILL_SUCCESS) { setJQPollingInfo(); // VACUUM should be called outside XACT // So, Commit XACT shouble be invoked beforehand. DBObj->commitTransaction(); // end XACT xactState = NOT_IN_XACT; } else { DBObj->rollbackTransaction(); xactState = NOT_IN_XACT; } return st; }
/*! process NewClassAd command, working with DBMS * \param key key * \param mytype mytype * \param ttype targettype * \return the result status * 0: error * 1: success */ QuillErrCode JobQueueDBManager::processNewClassAd(char* key, char* mytype, char* ttype) { MyString sql_str; char cid[512]; char pid[512]; int job_id_type; const char *data_arr[4]; QuillAttrDataType data_typ[4]; // It could be ProcAd or ClusterAd // So need to check job_id_type = getProcClusterIds(key, cid, pid); switch(job_id_type) { case IS_CLUSTER_ID: sql_str.formatstr("INSERT INTO ClusterAds_Horizontal (scheddname, cluster_id) VALUES ('%s', '%s')", scheddname, cid); break; case IS_PROC_ID: sql_str.formatstr("INSERT INTO ProcAds_Horizontal (scheddname, cluster_id, proc_id) VALUES ('%s', '%s', '%s')", scheddname, cid, pid); break; case IS_UNKNOWN_ID: dprintf(D_ALWAYS, "New ClassAd Processing --- ERROR\n"); return QUILL_FAILURE; // return a error code, 0 break; } { if (DBObj->execCommand(sql_str.Value()) == QUILL_FAILURE) { displayErrorMsg("New ClassAd Processing --- ERROR"); return QUILL_FAILURE; } } return QUILL_SUCCESS; }
void JobQueueDBManager::config(bool reconfig) { char *tmp; MyString sql_str; int bndcnt = 0; const char *data_arr[3]; QuillAttrDataType data_typ[3]; if (param_boolean("QUILL_ENABLED", false) == false) { EXCEPT("Quill++ is currently disabled. Please set QUILL_ENABLED to " "TRUE if you want this functionality and read the manual " "about this feature since it requires other attributes to be " "set properly."); } //bail out if no SPOOL variable is defined since its used to //figure out the location of the job_queue.log file char *spool = param("SPOOL"); if(!spool) { EXCEPT("No SPOOL variable found in config file\n"); } jobQueueLogFile = (char *) malloc(_POSIX_PATH_MAX * sizeof(char)); snprintf(jobQueueLogFile,_POSIX_PATH_MAX * sizeof(char), "%s/job_queue.log", spool); /* Here we try to read the database parameters in config the db ip address format is <ipaddress:port> */ dt = getConfigDBType(); jobQueueDBIpAddress = param("QUILL_DB_IP_ADDR"); jobQueueDBName = param("QUILL_DB_NAME"); jobQueueDBUser = param("QUILL_DB_USER"); jobQueueDBConn = getDBConnStr(jobQueueDBIpAddress, jobQueueDBName, jobQueueDBUser, spool); dprintf(D_ALWAYS, "Using Job Queue File %s\n", jobQueueLogFile); dprintf(D_ALWAYS, "Using Database Type = Postgres\n"); dprintf(D_ALWAYS, "Using Database IpAddress = %s\n", jobQueueDBIpAddress?jobQueueDBIpAddress:""); dprintf(D_ALWAYS, "Using Database Name = %s\n", jobQueueDBName?jobQueueDBName:""); dprintf(D_ALWAYS, "Using Database User = %s\n", jobQueueDBUser?jobQueueDBUser:""); if(spool) { free(spool); spool = NULL; } // this function is also called when condor_reconfig is issued // and so we dont want to recreate all essential objects if(!reconfig) { prober = new ClassAdLogProber(); caLogParser = new ClassAdLogParser(); switch (dt) { case T_PGSQL: DBObj = new PGSQLDatabase(jobQueueDBConn); break; default: break;; } xactState = NOT_IN_XACT; QuillErrCode ret_st; ret_st = DBObj->connectDB(); if (ret_st == QUILL_FAILURE) { displayErrorMsg("config: unable to connect to DB--- ERROR"); EXCEPT("config: unable to connect to DB\n"); } /* the following will also throw an exception if the schema version is not correct */ DBObj->assertSchemaVersion(); tmp = param( "SCHEDD_NAME" ); if( tmp ) { scheddname = build_valid_daemon_name( tmp ); dprintf(D_FULLDEBUG, "scheddname %s built from param value %s\n", scheddname, tmp); free(tmp); } else { scheddname = default_daemon_name(); dprintf(D_FULLDEBUG, "scheddname built from default daemon name: %s\n", scheddname); } { /* create an entry in jobqueuepollinginfo if this schedd is the * first time being logged to database */ sql_str.formatstr("INSERT INTO jobqueuepollinginfo (scheddname, last_file_mtime, last_file_size) SELECT '%s', 0, 0 FROM dummy_single_row_table WHERE NOT EXISTS (SELECT * FROM jobqueuepollinginfo WHERE scheddname = '%s')", scheddname, scheddname); ret_st = DBObj->execCommand(sql_str.Value()); if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Insert JobQueuePollInfo --- ERROR [SQL] %s\n", sql_str.Value()); } } { /* create an entry in currency table if this schedd is the first * time being logged to database */ sql_str.formatstr("INSERT INTO currencies (datasource) SELECT '%s' FROM dummy_single_row_table WHERE NOT EXISTS (SELECT * FROM currencies WHERE datasource = '%s')", scheddname, scheddname); ret_st = DBObj->execCommand(sql_str.Value()); if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Insert Currency --- ERROR [SQL] %s\n", sql_str.Value()); } } ret_st = DBObj->commitTransaction(); if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Commit transaction failed in JobQueueDBManager::config\n"); } if (param_boolean("QUILL_MAINTAIN_DB_CONN", true) == false) { ret_st = DBObj->disconnectDB(); if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "JobQueueDBManager:config: unable to disconnect database --- ERROR\n"); } } } //this function assumes that certain members have been initialized // (specifically prober and caLogParser) and so the order is important. setJobQueueFileName(jobQueueLogFile); }
//! get Last Job Queue File Polling Information QuillErrCode JobQueueDBManager::getJQPollingInfo() { long mtime; long size; ClassAdLogEntry* lcmd; MyString sql_str; int ret_st; int num_result; lcmd = caLogParser->getCurCALogEntry(); dprintf(D_FULLDEBUG, "Get JobQueue Polling Information\n"); sql_str.formatstr("SELECT last_file_mtime, last_file_size, last_next_cmd_offset, last_cmd_offset, last_cmd_type, last_cmd_key, last_cmd_mytype, last_cmd_targettype, last_cmd_name, last_cmd_value from JobQueuePollingInfo where scheddname = '%s'", scheddname); ret_st = DBObj->execQuery(sql_str.Value(), num_result); if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Reading JobQueuePollInfo --- ERROR [SQL] %s\n", sql_str.Value()); displayErrorMsg("Reading JobQueuePollInfo --- ERROR"); return QUILL_FAILURE; } else if (ret_st == QUILL_SUCCESS && num_result == 0) { // This case is a rare one since the jobqueuepollinginfo // table contains one tuple at all times displayErrorMsg("Reading JobQueuePollingInfo --- ERROR " "No Rows Retrieved from JobQueuePollingInfo\n"); DBObj->releaseQueryResult(); // release Query Result return QUILL_FAILURE; } mtime = atoi(DBObj->getValue(0, 0)); // last_file_mtime size = atoi(DBObj->getValue(0, 1)); // last_file_size prober->setLastModifiedTime(mtime); prober->setLastSize(size); // last_next_cmd_offset lcmd->next_offset = atoi(DBObj->getValue(0,2)); lcmd->offset = atoi(DBObj->getValue(0,3)); // last_cmd_offset lcmd->op_type = atoi(DBObj->getValue(0,4)); // last_cmd_type if (lcmd->key) { free(lcmd->key); } if (lcmd->mytype) { free(lcmd->mytype); } if (lcmd->targettype) { free(lcmd->targettype); } if (lcmd->name) { free(lcmd->name); } if (lcmd->value) { free(lcmd->value); } lcmd->key = strdup(DBObj->getValue(0,5)); // last_cmd_key lcmd->mytype = strdup(DBObj->getValue(0,6)); // last_cmd_mytype // last_cmd_targettype lcmd->targettype = strdup(DBObj->getValue(0,7)); lcmd->name = strdup(DBObj->getValue(0,8)); // last_cmd_name lcmd->value = strdup(DBObj->getValue(0,9)); // last_cmd_value DBObj->releaseQueryResult(); // release Query Result // since it is no longer needed return QUILL_SUCCESS; }
/*! process SetAttribute command, working with DBMS * \param key key * \param name attribute name * \param value attribute value * \return the result status * 0: error * 1: success * Note: * Because this is not just update, but set. So, we need to delete and insert * it. We twiddled with an alternative way to do it (using NOT EXISTS) but * found out that DELETE/INSERT works as efficiently. the old sql is kept * around in case :) */ QuillErrCode JobQueueDBManager::processSetAttribute(char* key, char* name, char* value) { MyString sql_str_del_in; MyString sql_str2 = ""; char cid[512]; char pid[512]; int job_id_type; //int ret_st; MyString newvalue; const char *data_arr1[6]; QuillAttrDataType data_typ1[6]; const char *data_arr2[6]; QuillAttrDataType data_typ2[6]; QuillAttrDataType attr_type; MyString ts_expr_val; // It could be ProcAd or ClusterAd // So need to check job_id_type = getProcClusterIds(key, cid, pid); switch(job_id_type) { case IS_CLUSTER_ID: if(isHorizontalClusterAttribute(name, attr_type)) { if (attr_type == CONDOR_TT_TYPE_TIMESTAMP) { time_t clock; clock = atoi(value); { MyString ts_expr; ts_expr = condor_ttdb_buildts(&clock, dt); if (ts_expr.IsEmpty()) { dprintf(D_ALWAYS, "ERROR: Timestamp expression not built in JobQueueDBManager::processSetAttribute\n"); return QUILL_FAILURE; } sql_str_del_in.formatstr( "UPDATE ClusterAds_Horizontal SET %s = (%s) WHERE scheddname = '%s' and cluster_id = '%s'", name, ts_expr.Value(), scheddname, cid); } } else { // strip double quote for string type values if ((attr_type == CONDOR_TT_TYPE_STRING || attr_type == CONDOR_TT_TYPE_CLOB) && !stripdoublequotes(value)) { dprintf(D_ALWAYS, "ERROR: string constant not double quoted for attribute %s in JobQueueDBManager::ProcessSetAttribute\n", name); } newvalue = condor_ttdb_fillEscapeCharacters(value, dt); // escape single quote within the value { sql_str_del_in.formatstr("UPDATE ClusterAds_Horizontal SET %s = '%s' WHERE scheddname = '%s' and cluster_id = '%s'", name, newvalue.Value(), scheddname, cid); } } } else { newvalue = condor_ttdb_fillEscapeCharacters(value, dt); { sql_str_del_in.formatstr("DELETE FROM ClusterAds_Vertical WHERE scheddname = '%s' and cluster_id = '%s' AND attr = '%s'", scheddname, cid, name); } { sql_str2.formatstr("INSERT INTO ClusterAds_Vertical (scheddname, cluster_id, attr, val) VALUES ('%s', '%s', '%s', '%s')", scheddname, cid, name, newvalue.Value()); } } break; case IS_PROC_ID: if(isHorizontalProcAttribute(name, attr_type)) { if (attr_type == CONDOR_TT_TYPE_TIMESTAMP) { time_t clock; clock = atoi(value); { MyString ts_expr; ts_expr = condor_ttdb_buildts(&clock, dt); if (ts_expr.IsEmpty()) { dprintf(D_ALWAYS, "ERROR: Timestamp expression not built in JobQueueDBManager::processSetAttribute\n"); return QUILL_FAILURE; } sql_str_del_in.formatstr( "UPDATE ProcAds_Horizontal SET %s = (%s) WHERE scheddname = '%s' and cluster_id = '%s' and proc_id = '%s'", name, ts_expr.Value(), scheddname, cid, pid); } } else { // strip double quote for string type values if ((attr_type == CONDOR_TT_TYPE_STRING || attr_type == CONDOR_TT_TYPE_CLOB) && !stripdoublequotes(value)) { dprintf(D_ALWAYS, "ERROR: string constant not double quoted for attribute %s in JobQueueDBManager::ProcessSetAttribute\n", name); } newvalue = condor_ttdb_fillEscapeCharacters(value, dt); { sql_str_del_in.formatstr("UPDATE ProcAds_Horizontal SET %s = '%s' WHERE scheddname = '%s' and cluster_id = '%s' and proc_id = '%s'", name, newvalue.Value(), scheddname, cid, pid); } } } else { newvalue = condor_ttdb_fillEscapeCharacters(value, dt); { sql_str_del_in.formatstr("DELETE FROM ProcAds_Vertical WHERE scheddname = '%s' and cluster_id = '%s' AND proc_id = '%s' AND attr = '%s'", scheddname, cid, pid, name); } { sql_str2.formatstr("INSERT INTO ProcAds_Vertical (scheddname, cluster_id, proc_id, attr, val) VALUES ('%s', '%s', '%s', '%s', '%s')", scheddname, cid, pid, name, newvalue.Value()); } } break; case IS_UNKNOWN_ID: dprintf(D_ALWAYS, "Set Attribute Processing --- ERROR\n"); return QUILL_FAILURE; break; } QuillErrCode ret_st; { ret_st = DBObj->execCommand(sql_str_del_in.Value()); } if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Set Attribute --- Error [SQL] %s\n", sql_str_del_in.Value()); displayErrorMsg("Set Attribute --- ERROR"); return QUILL_FAILURE; } if (!sql_str2.IsEmpty()) { { ret_st = DBObj->execCommand(sql_str2.Value()); } if (ret_st == QUILL_FAILURE) { dprintf(D_ALWAYS, "Set Attribute --- Error [SQL] %s\n", sql_str2.Value()); displayErrorMsg("Set Attribute --- ERROR"); return QUILL_FAILURE; } } return QUILL_SUCCESS; }
void Preferences::interfacetest() { QMessageBox *msgbox; FSSM_WaitMsgBox *waitmsgbox = NULL; QFont msgboxfont; // PREPARE INTERFACE: AbstractDiagInterface *diagInterface = NULL; if (_newinterfacetype == AbstractDiagInterface::interface_serialPassThrough) { diagInterface = new SerialPassThroughDiagInterface; } else if (_newinterfacetype == AbstractDiagInterface::interface_J2534) { diagInterface = new J2534DiagInterface; } else if (_newinterfacetype == AbstractDiagInterface::interface_ATcommandControlled) { diagInterface = new ATcommandControlledDiagInterface; } else { displayErrorMsg(tr("The selected interface is not supported !")); displayErrorMsg(tr("Internal error:\nThe interface test for the selected interface is not yet implemented.\n=> Please report this as a bug.")); return; } // OPEN INTERFACE: if (!diagInterface->open(_newinterfacefilename.toStdString())) { displayErrorMsg(tr("Couldn't open the diagnostic interface !\nPlease make sure that the device is not in use by another application.")); delete diagInterface; return; } // DISPLAY INFO MESSAGE: int choice = QMessageBox::NoButton; msgbox = new QMessageBox( QMessageBox::Information, tr("Interface test"), tr("Please connect diagnostic interface to the vehicles\ndiagnostic connector and switch ignition on."), QMessageBox::NoButton, this); msgbox->addButton(tr("Start"), QMessageBox::AcceptRole); msgbox->addButton(tr("Cancel"), QMessageBox::RejectRole); msgboxfont = msgbox->font(); msgboxfont.setPixelSize(12); // 9pts msgbox->setFont( msgboxfont ); msgbox->show(); choice = msgbox->exec(); msgbox->close(); delete msgbox; if (choice == QMessageBox::AcceptRole) { // START INTERFACE-TEST: bool icresult = false; bool retry = true; choice = 0; bool SSM1configOK = false; bool SSM2configOK = false; while (retry && !icresult) { char data = 0; // OUTPUT WAIT MESSAGE: waitmsgbox = new FSSM_WaitMsgBox(this, tr("Testing interface... Please wait ! ")); waitmsgbox->show(); // SSM2: SSMP2communication *SSMP2com = new SSMP2communication(diagInterface); SSM2configOK = diagInterface->connect(AbstractDiagInterface::protocol_SSM2_ISO14230); if (SSM2configOK) { SSMP2com->setCUaddress(0x10); unsigned int addr = 0x61; icresult = SSMP2com->readMultipleDatabytes('\x0', &addr, 1, &data); if (!icresult) { SSMP2com->setCUaddress(0x01); icresult = SSMP2com->readMultipleDatabytes('\x0', &addr, 1, &data); if (!icresult) { SSMP2com->setCUaddress(0x02); icresult = SSMP2com->readMultipleDatabytes('\x0', &addr, 1, &data); } } diagInterface->disconnect(); } if (!icresult) { SSM2configOK = diagInterface->connect(AbstractDiagInterface::protocol_SSM2_ISO15765); if (SSM2configOK) { SSMP2com->setCUaddress(0x7E0); unsigned int addr = 0x61; icresult = SSMP2com->readMultipleDatabytes('\x0', &addr, 1, &data); diagInterface->disconnect(); } } delete SSMP2com; // SSM1: if (!icresult) { SSM1configOK = diagInterface->connect(AbstractDiagInterface::protocol_SSM1); if (SSM1configOK) { SSMP1communication *SSMP1com = new SSMP1communication(diagInterface, SSM1_CU_Engine); icresult = SSMP1com->readAddress(0x00, &data); if (!icresult) { SSMP1com->selectCU(SSM1_CU_Transmission); icresult = SSMP1com->readAddress(0x00, &data); delete SSMP1com; } diagInterface->disconnect(); } } // CLOSE WAIT MESSAGE: waitmsgbox->close(); delete waitmsgbox; // DISPLAY TEST RESULT: QString resultText; if (icresult) resultText = tr("Interface test successful !"); else resultText = tr("Interface test failed !"); if (!SSM1configOK && !SSM2configOK) // => test must have failed { if (_newinterfacetype == AbstractDiagInterface::interface_serialPassThrough) resultText += "\n\n" + tr("The selected serial port can not be configured for the SSM1- and SSM2-protocol."); else resultText += "\n\n" + tr("The selected interface does not support the SSM1- and SSM2-protocol."); } else if (!icresult) { resultText += "\n\n" + tr("Please make sure that the interface is connected properly and ignition is switched ON."); } if (!SSM1configOK || !SSM2configOK) { resultText += "\n\n" + tr("WARNING:"); if (!SSM1configOK) { if (_newinterfacetype == AbstractDiagInterface::interface_serialPassThrough) resultText += '\n' + tr("The selected serial port can not be configured for the SSM1-protocol."); else resultText += '\n' + tr("The selected interface does not support the SSM1-protocol."); } else if (!SSM2configOK) { if (_newinterfacetype == AbstractDiagInterface::interface_serialPassThrough) resultText += '\n' + tr("The selected serial port can not be configured for the SSM2-protocol."); else resultText += '\n' + tr("The selected interface does not support the SSM2-protocol."); } } if (icresult) msgbox = new QMessageBox(QMessageBox::Information, tr("Interface test"), resultText, QMessageBox::Ok, this); else { msgbox = new QMessageBox(QMessageBox::Critical, tr("Interface test"), resultText, QMessageBox::NoButton, this); msgbox->addButton(tr("Retry"), QMessageBox::AcceptRole); msgbox->addButton(tr("Cancel"), QMessageBox::RejectRole); } msgboxfont = msgbox->font(); msgboxfont.setPixelSize(12); // 9pts msgbox->setFont( msgboxfont ); msgbox->show(); choice = msgbox->exec(); msgbox->close(); delete msgbox; if (!icresult && (choice != QMessageBox::AcceptRole)) retry = false; } } // CLOSE INTERFACE: if (!diagInterface->close()) displayErrorMsg(tr("Couldn't close the diagnostic interface !")); delete diagInterface; }