public static double getDataRate(final NamedElement ne, final double defaultValue) { // TODO add in new Input_Rate or OutPut_Rate property from V2 try { Property dataRate = GetProperties.lookupPropertyDefinition(ne, "SEI", "Data_Rate"); return PropertyUtils.getRealValue(ne, dataRate, defaultValue); } catch (Throwable e) { return defaultValue; } }
protected double sumMemoryActuals(ComponentInstance ci, boolean isROM) { try { double total = isROM ? GetProperties.getROMActualInKB(ci, 0.0) : GetProperties.getRAMActualInKB(ci, 0.0); EList subcis = ci.getComponentInstances(); for (Iterator it = subcis.iterator(); it.hasNext(); ) { ComponentInstance subci = (ComponentInstance) it.next(); total += sumMemoryActuals(subci, isROM); } return total; } catch (PropertyDoesNotApplyToHolderException e) { /* * Callers are allowed to be sloppy and not care if the property * actually applies to the category of the component instance 'ci' */ return 0.0; } }
/** * check the load from components bound to the given memory The components can be threads or * higher level components. * * @param curMemory Component Instance of memory */ protected void checkMemoryLoad(ComponentInstance curMemory, final SystemOperationMode som) { SystemInstance root = curMemory.getSystemInstance(); final ComponentInstance currentMemory = curMemory; final String somName = som.getName(); long timeBefore = System.currentTimeMillis(); OsateDebug.osateDebug("[Memory] before get sw comps (memory=" + curMemory.getName() + ")"); EList<ComponentInstance> boundComponents = InstanceModelUtil.getBoundSWComponents(curMemory); long timeAfter = System.currentTimeMillis(); long period = timeAfter - timeBefore; OsateDebug.osateDebug("[CPU] after get sw comps, time taken=" + period + "ms"); if (GetProperties.getROMCapacityInKB(curMemory, 0.0) > 0.0) { doMemoryLoad(curMemory, somName, boundComponents, true); // ROM } if (GetProperties.getRAMCapacityInKB(curMemory, 0.0) > 0.0) { doMemoryLoad(curMemory, somName, boundComponents, false); // RAM } }
/** * Calculate bandwidth demand from rate & data size * * @param pci Port connection instance * @return */ protected double calcBandwidthKBytesps(ConnectionInstanceEnd cie) { double res = 0; // TODO-LW add other cases if (cie instanceof FeatureInstance) { FeatureInstance fi = (FeatureInstance) cie; double datasize = GetProperties.getSourceDataSize(fi, GetProperties.getKBUnitLiteral(fi)); double srcRate = getDataRate(fi, 0.0); if (srcRate == 0) { double period = GetProperties.getPeriodInSeconds(fi.getContainingComponentInstance(), 0); if (period == 0) return res; srcRate = 1 / GetProperties.getPeriodInSeconds(fi.getContainingComponentInstance(), 1); } res = datasize * srcRate; EList fil = fi.getFeatureInstances(); if (fil.size() > 0) { double subres = 0; for (Iterator it = fil.iterator(); it.hasNext(); ) { FeatureInstance sfi = (FeatureInstance) it.next(); subres = subres + calcBandwidthKBytesps(sfi); } if (subres > res) { if (res > 0) { errManager.warningSummary( fi, null, "Bandwidth of feature group ports " + subres + " exceeds feature group bandwidth " + res); } res = subres; } } } return res; }
public Section export() { Section section; Line line; double minValue; double maxValue; double minSpecifiedValue; double maxSpecifiedValue; double expectedMaxLatency; double expectedMinLatency; String sectionName; minValue = 0.0; maxValue = 0.0; minSpecifiedValue = 0.0; maxSpecifiedValue = 0.0; issues = new ArrayList<ReportedCell>(); expectedMaxLatency = GetProperties.getMaximumLatencyinMilliSec(this.relatedEndToEndFlow); expectedMinLatency = GetProperties.getMinimumLatencyinMilliSec(this.relatedEndToEndFlow); if (relatedEndToEndFlow != null) { sectionName = relatedEndToEndFlow.getComponentInstancePath(); } else { sectionName = "Unnamed flow"; } section = new Section(sectionName + getSyncLabel()); line = new Line(); line.addHeaderContent("Contributor"); line.addHeaderContent("Min Specified"); line.addHeaderContent("Min Value"); line.addHeaderContent("Min Method"); line.addHeaderContent("Max Specified"); line.addHeaderContent("Max Value"); line.addHeaderContent("Max Method"); line.addHeaderContent("Comments"); section.addLine(line); // will populate the comments section minValue = getMinimumActualLatency(); maxValue = getMaximumActualLatency(); minSpecifiedValue = getMinimumSpecifiedLatency(); maxSpecifiedValue = getMaximumSpecifiedLatency(); // reporting each entry for (LatencyContributor lc : this.contributors) { if (!skipMeInReport(lc)) { for (Line l : lc.export()) { section.addLine(l); } } } line = new Line(); line.addContent("Latency Total"); line.addContent(minSpecifiedValue + "ms"); line.addContent(minValue + "ms"); line.addContent(""); line.addContent(maxSpecifiedValue + "ms"); line.addContent(maxValue + "ms"); line.addContent(""); section.addLine(line); line = new Line(); line.setSeverity(ReportSeverity.SUCCESS); line.addContent("End to End Latency"); line.addContent(""); line.addContent(expectedMinLatency + "ms"); line.addContent(""); line.addContent(""); line.addContent(expectedMaxLatency + "ms"); line.addContent(""); /* * In that case, the end to end flow has a minimum latency */ if (expectedMinLatency > 0) { if (expectedMinLatency < minSpecifiedValue) { reportSummaryWarning( "Sum of minimum specified latencies (" + minSpecifiedValue + " ms) is greater than minimum end to end latency (" + expectedMinLatency + "ms)"); } if (expectedMinLatency < minValue) { reportSummaryError( "Sum of minimum actual latencies (" + minValue + " ms) is greater than minimum end to end latency (" + expectedMinLatency + "ms)"); } } else { reportSummaryWarning("Minimum end to end latency is not pecified or zero"); } /** Here, the max latency value has been defined */ if (expectedMaxLatency > 0) { if (expectedMaxLatency < maxSpecifiedValue) { reportSummaryError( "Sum of maximum specified latency (" + maxSpecifiedValue + "ms) exceeds end to end latency (" + expectedMaxLatency + "ms)"); } if (expectedMaxLatency < maxValue) { reportSummaryError( "Sum of maximum actual latencies (" + maxValue + "ms) exceeds end to end latency (" + expectedMaxLatency + "ms)"); } } else { reportSummaryWarning("End to end latency is not specified"); } /** * If the expected latency is defined and consistent with the max value, everything should be ok * It means that the number calculated from the component is correct and less than the latency * specifications. In case of Min latency the actual sum should be higher. */ if ((minValue > 0) && (maxValue > 0) && (expectedMaxLatency > 0) && (expectedMinLatency > 0) && (minValue >= expectedMinLatency) && (expectedMaxLatency >= maxValue)) { reportSummaryInfo( "end-to-end flow latency for " + this.relatedEndToEndFlow.getName() + " calculated from the components is correct with the expected latency specifications"); } section.addLine(line); if (issues.size() > 0) { line = new Line(); line.addHeaderContent("End to end Latency Summary"); section.addLine(line); for (ReportedCell issue : issues) { line = new Line(); String msg = issue.getMessage(); issue.setMessage(issue.getSeverity().toString()); line.addCell(issue); line.addContent(msg); section.addLine(line); } } return section; }
/** * check the load from connections bound to the given bus * * @param curBus Component Instance of bus * @param doBindings if true do bindings to all buses, if false do them only for EtherSwitch * @param somName String somName to be used in messages */ protected void checkBandWidthLoad(final ComponentInstance curBus, SystemOperationMode som) { UnitLiteral kbspsliteral = GetProperties.getKBytespsUnitLiteral(curBus); double Buscapacity = GetProperties.getBandWidthCapacityInKbps(curBus, 0.0); boolean doBroadcast = GetProperties.isBroadcastProtocol(curBus); SystemInstance root = curBus.getSystemInstance(); double totalBandWidth = 0.0; EList<ConnectionInstance> budgetedConnections = InstanceModelUtil.getBoundConnections(curBus); // filters out to use only Port connections or feature group connections // it also tries to be smart about not double accounting for budgets on FG that now show for // every port instance inside. /* ConnectionGroupIterator cgi = new ConnectionGroupIterator(connections); while (cgi.hasNext()) { ConnectionInstance obj = cgi.next(); if (obj != null) { if (InstanceModelUtil.isBoundToBus(obj, curBus)|| // we derived a bus connection from the connection end bindings (!InstanceModelUtil.hasBusBinding(obj)&&InstanceModelUtil.connectedByBus(obj, curBus)) ) { if ((obj.getSource().isActive(som)) && (obj.getDestination().isActive(som))) { budgetedConnections.add(obj); } } } }*/ if (doBroadcast) { budgetedConnections = filterSameSourceConnections(budgetedConnections); } if (Buscapacity == 0) { if (!budgetedConnections.isEmpty()) { errManager.warningSummary( curBus, som.getName(), curBus.getComponentInstancePath() + " has no capacity but bound connections"); } else { errManager.warningSummary( curBus, som.getName(), curBus.getComponentInstancePath() + " has no capacity"); return; } } if (budgetedConnections.isEmpty()) { errManager.infoSummary( curBus, som.getName(), curBus.getComponentInstancePath() + " with bandwidth capacity " + Buscapacity + "KBytesps has no bound connections"); return; } if (som != null) { errManager.logInfo( "\n\nConnection Budget Details for bus " + curBus.getFullName() + " in mode " + som.getName() + " with capacity " + Buscapacity + "KBytesps\n"); } else { errManager.logInfo( "\n\nConnection Budget Details for bus " + curBus.getFullName() + " with capacity " + Buscapacity + "KBytesps\n"); } errManager.logInfo("Connection,Budget,Actual (Data Size * Sender Rate),Note"); for (ConnectionInstance connectionInstance : budgetedConnections) { double budget = 0.0; double actual = 0.0; if ((!connectionInstance.getSource().isActive(som)) || (!connectionInstance.getDestination().isActive(som))) { continue; } // we have a binding, is it to the current bus budget = GetProperties.getBandWidthBudgetInKbps(connectionInstance, 0.0); actual = calcBandwidthKBytesps(connectionInstance.getSource()); String note = ""; if (budget > 0) { if ((actual > 0) && (actual > budget)) { totalBandWidth += actual; note = "Actual bandwidth exceeds bandwidth budget. Using actual"; } else { totalBandWidth += budget; note = "Using budget bandwidth"; } } else { if (actual > 0) { totalBandWidth += actual; note = "No bandwidth budget. Using actual"; } else { note = "No bandwidth budget or actual bandwidth from port data size&rate"; } } detailedLog(connectionInstance, budget, actual, note); } detailedLog(null, totalBandWidth, kbspsliteral); if (totalBandWidth > Buscapacity) { errManager.errorSummary( curBus, som.getName(), curBus.getComponentInstancePath() + " bandwidth capacity " + Buscapacity + " KBytesps exceeded by connection bandwidth budget totals " + totalBandWidth + " Kbps"); } else if (totalBandWidth > 0.0 && Buscapacity > 0.0) { errManager.infoSummary( curBus, som.getName(), curBus.getComponentInstancePath() + " bandwidth capacity " + Buscapacity + " KBytesps sufficient for connection bandwidth budget totals " + totalBandWidth + " Kbps"); } }
/** * check the load from connections bound to the given bus * * @param curBus Component Instance of bus * @param doBindings if true do bindings to all buses, if false do them only for EtherSwitch * @param somName String somName to be used in messages */ protected double calcBandWidthLoad(SystemInstance root, final SystemOperationMode som) { double totalBandWidth = 0.0; EList<ConnectionInstance> connections = root.getAllConnectionInstances(); EList<ConnectionInstance> budgetedConnections = new BasicEList<ConnectionInstance>(); // filters out to use only Port connections or feature group connections // it also tries to be smart about not double accounting for budgets on FG that now show for // every port instance inside. ConnectionGroupIterator cgi = new ConnectionGroupIterator(connections); while (cgi.hasNext()) { ConnectionInstance obj = cgi.next(); if (obj != null) budgetedConnections.add(obj); } for (ConnectionInstance connectionInstance : budgetedConnections) { if ((connectionInstance.getSource().getContainingComponentInstance() != null) && (!connectionInstance.getSource().getContainingComponentInstance().isActive(som))) { OsateDebug.osateDebug("[DoBoundResourceAnalysis] source not active in mode=" + som); continue; } if ((connectionInstance.getDestination().getContainingComponentInstance() != null) && (!connectionInstance .getDestination() .getContainingComponentInstance() .isActive(som))) { OsateDebug.osateDebug("[DoBoundResourceAnalysis] destination not active in mode=" + som); continue; } OsateDebug.osateDebug( "[DoBoundResourceAnalysis] source=" + connectionInstance.getSource().getContainingComponentInstance()); double budget = GetProperties.getBandWidthBudgetInKbps(connectionInstance, 0.0); double actual = calcBandwidthKBytesps(connectionInstance.getSource()); String note = ""; OsateDebug.osateDebug("[DoBoundResourceAnalysis] total=" + totalBandWidth); OsateDebug.osateDebug("[DoBoundResourceAnalysis] actual=" + actual); OsateDebug.osateDebug("[DoBoundResourceAnalysis] budget=" + budget); if (budget > 0) { if ((actual > 0) && (actual > budget)) { totalBandWidth += actual; note = "Actual bandwidth exceeds bandwidth budget. Using actual"; } else { note = "Using budget bandwidth"; totalBandWidth += budget; } } else { if (actual > 0) { totalBandWidth = totalBandWidth + actual; note = "No bandwidth budget. Using actual"; } else { note = "No bandwidth budget or actual"; } } detailedLog(connectionInstance, budget, actual, note); } OsateDebug.osateDebug("[DoBoundResourceAnalysis] res=" + totalBandWidth); return totalBandWidth; }
/** * check the load from components bound to the given memory The components can be threads or * higher level components. * * @param curMemory Component Instance of memory */ protected void doMemoryLoad( ComponentInstance curMemory, String somName, EList boundComponents, boolean isROM) { double totalMemory = 0.0; UnitLiteral kbliteral = GetProperties.getKBUnitLiteral(curMemory); String resourceName = isROM ? "ROM" : "RAM"; double Memorycapacity = isROM ? GetProperties.getROMCapacityInKB(curMemory, 0.0) : GetProperties.getRAMCapacityInKB(curMemory, 0.0); if (boundComponents.size() == 0 && Memorycapacity > 0) { errManager.infoSummary( curMemory, somName, "No application components bound to " + curMemory.getComponentInstancePath() + " with " + resourceName + " capacity " + GetProperties.toStringScaled(Memorycapacity, kbliteral)); return; } if (Memorycapacity == 0) { errManager.errorSummary( curMemory, somName, "Memory " + curMemory.getComponentInstancePath() + " has no " + resourceName + " capacity but has bound components."); } logHeader( "\n\nDetailed Workload Report for memory " + curMemory.getComponentInstancePath() + " with Capacity " + GetProperties.toStringScaled(Memorycapacity, kbliteral) + "\n\nComponent,Budget,Actual"); Set budgeted = new HashSet(); for (Iterator it = boundComponents.iterator(); it.hasNext(); ) { String notes = ""; ComponentInstance bci = (ComponentInstance) it.next(); double totalactual = sumMemoryActuals(bci, isROM); double budget = isROM ? GetProperties.getROMBudgetInKB(bci, 0.0) : GetProperties.getRAMBudgetInKB(bci, 0.0); if (totalactual > 0) { // only compare if there were actuals if (totalactual > budget) { notes = notes + ",Error: " + resourceName + " subtotal exceeds budget by " + (totalactual - budget) + " KB"; } else if (totalactual < budget) { notes = notes + ",Warning: " + resourceName + " Subtotal under budget by " + (budget - totalactual) + " KB"; } } if (totalactual == 0.0) { // we use a budget number as there are no actuals if (budget > 0 && !budgeted.contains(bci)) { // only add it if no children budget numbers have been added totalMemory += budget; detailedLog(bci, budget, kbliteral); // add ancestors to budgeted list so their budget does not get added later while ((bci = bci.getContainingComponentInstance()) != null) { budgeted.add(bci); } } } else { // add only the current actual; the children actual have been added before double currentActual = isROM ? GetProperties.getROMActualInKB(bci, 0.0) : GetProperties.getRAMActualInKB(bci, 0.0); detailedLog(bci, budget, kbliteral); totalMemory += currentActual; } } if (Memorycapacity == 0) errManager.errorSummary( curMemory, somName, "" + (isROM ? "ROM" : "RAM") + " memory " + curMemory.getComponentInstancePath() + " has no memory capacity specified"); if (totalMemory > Memorycapacity) { errManager.errorSummary( curMemory, somName, "Total Memory " + totalMemory + " KB of bounds tasks exceeds Memory capacity " + Memorycapacity + " KB of " + curMemory.getComponentInstancePath()); } else if (totalMemory == 0.0 && Memorycapacity == 0.0) { errManager.warningSummary( curMemory, somName, "" + (isROM ? "ROM" : "RAM") + " memory " + curMemory.getComponentInstancePath() + " has no capacity. Bound app's have no memory budget."); } else { errManager.infoSummary( curMemory, somName, "Total " + (isROM ? "ROM" : "RAM") + " memory " + totalMemory + " KB of bound tasks within Memory capacity " + Memorycapacity + " KB of " + curMemory.getComponentInstancePath()); } }
/** * check the load from components bound to the given processor The components can be threads or * higher level components. * * @param curProcessor Component Instance of processor */ protected void checkProcessorLoad(ComponentInstance curProcessor, final SystemOperationMode som) { boolean isCPUActive; if (curProcessor.getSubcomponent().getAllInModes().size() == 0) { isCPUActive = true; } else { isCPUActive = false; for (Mode mi : curProcessor.getSubcomponent().getAllInModes()) { // OsateDebug.osateDebug("somName=" + somName + " mi=" + mi); if (som.getName().equalsIgnoreCase(mi.getName())) { // OsateDebug.osateDebug("cpu " + curProcessor.getName() + "is active for mode" + // somName); isCPUActive = true; } } } if (isCPUActive == false) { return; } UnitLiteral mipsliteral = GetProperties.getMIPSUnitLiteral(curProcessor); double MIPScapacity = GetProperties.getMIPSCapacityInMIPS(curProcessor, 0.0); if (MIPScapacity == 0 && InstanceModelUtil.isVirtualProcessor(curProcessor)) { MIPScapacity = GetProperties.getMIPSBudgetInMIPS(curProcessor); } long timeBefore = System.currentTimeMillis(); OsateDebug.osateDebug( "[CPU] before get sw comps (CPU=" + curProcessor.getName() + ",cat=" + curProcessor.getComponentClassifier().getCategory().getName() + ")"); EList<ComponentInstance> boundComponents = InstanceModelUtil.getBoundSWComponents(curProcessor); long timeAfter = System.currentTimeMillis(); long period = timeAfter - timeBefore; OsateDebug.osateDebug("[CPU] after get sw comps, time taken=" + period + "ms"); if (boundComponents.size() == 0 && MIPScapacity > 0) { errManager.infoSummary( curProcessor, som.getName(), "No application components bound to " + curProcessor.getComponentInstancePath() + " with MIPS capacity " + GetProperties.toStringScaled(MIPScapacity, mipsliteral)); return; } if (MIPScapacity == 0 && InstanceModelUtil.isVirtualProcessor(curProcessor)) { errManager.warningSummary( curProcessor, som.getName(), "Virtual processor " + curProcessor.getComponentInstancePath() + " has no MIPS capacity or budget."); return; } if (MIPScapacity == 0 && InstanceModelUtil.isProcessor(curProcessor)) { errManager.errorSummary( curProcessor, som.getName(), "Processor " + curProcessor.getComponentInstancePath() + " has no MIPS capacity but has bound components."); } if (InstanceModelUtil.isVirtualProcessor(curProcessor)) { logHeader( "\n\nDetailed Workload Report for Virtual Processor " + curProcessor.getComponentInstancePath() + " with Capacity " + GetProperties.toStringScaled(MIPScapacity, mipsliteral) + "\n\nComponent,Budget,Actual"); } else { logHeader( "\n\nDetailed Workload Report for Processor " + curProcessor.getComponentInstancePath() + " with Capacity " + GetProperties.toStringScaled(MIPScapacity, mipsliteral) + "\n\nComponent,Budget,Actual"); } double totalMIPS = 0.0; for (Iterator<ComponentInstance> it = boundComponents.iterator(); it.hasNext(); ) { ComponentInstance bci = (ComponentInstance) it.next(); boolean isComponentActive; if ((som == null) || (bci.getSubcomponent().getAllInModes().size() == 0)) { isComponentActive = true; } else { isComponentActive = false; for (Mode mi : bci.getSubcomponent().getAllInModes()) { // OsateDebug.osateDebug("somName=" + somName + " mi=" + mi); if (som.getName().equalsIgnoreCase(mi.getName())) { // OsateDebug.osateDebug("cpu " + curProcessor.getName() + "is active for mode" + // somName); isComponentActive = true; } } } if (isComponentActive == true) { double actualmips = sumBudgets(bci, ResourceKind.MIPS, mipsliteral, true, som, ""); totalMIPS += actualmips; } } logHeader("Total," + GetProperties.toStringScaled(totalMIPS, mipsliteral)); if (totalMIPS > MIPScapacity) { errManager.errorSummary( curProcessor, som.getName(), "Total MIPS " + GetProperties.toStringScaled(totalMIPS, mipsliteral) + " of bound tasks exceeds MIPS capacity " + GetProperties.toStringScaled(MIPScapacity, mipsliteral) + " of " + curProcessor.getComponentInstancePath()); } else if (totalMIPS == 0.0) { errManager.warningSummary(curProcessor, som.getName(), "Bound app's have no MIPS budget."); } else { errManager.infoSummary( curProcessor, som.getName(), "Total MIPS " + GetProperties.toStringScaled(totalMIPS, mipsliteral) + " of bound tasks within " + "MIPS capacity " + GetProperties.toStringScaled(MIPScapacity, mipsliteral) + " of " + curProcessor.getComponentInstancePath()); } }
public void checkPortConsistency( FeatureInstance srcFI, FeatureInstance dstFI, ConnectionInstance conni) { double srcDataSize = GetProperties.getSourceDataSizeInBytes(srcFI); double dstDataSize = GetProperties.getSourceDataSizeInBytes(dstFI); RecordValue srcRate = GetProperties.getOutPutRate(srcFI); RecordValue dstRate = GetProperties.getInPutRate(dstFI); EnumerationLiteral srcRU = null; EnumerationLiteral dstRU = null; double srcMaxRateValue = 0; double dstMaxRateValue = 0; double srcMinRateValue = 0; double dstMinRateValue = 0; if (srcRate != null && dstRate != null) { srcRU = GetProperties.getRateUnit(srcRate); dstRU = GetProperties.getRateUnit(dstRate); srcMaxRateValue = GetProperties.getMaxDataRate(srcRate); dstMaxRateValue = GetProperties.getMaxDataRate(dstRate); srcMinRateValue = GetProperties.getMinDataRate(srcRate); dstMinRateValue = GetProperties.getMinDataRate(dstRate); } // now try it as SEI::Data_Rate double srcRateValue = GetProperties.getMessageRatePerSecond(srcFI); double dstRateValue = GetProperties.getMessageRatePerSecond(dstFI); Classifier srcC = GetProperties.getSingleBaseType(srcFI); Classifier dstC = GetProperties.getSingleBaseType(dstFI); String srcS = GetProperties.getMeasurementUnit(srcFI); String dstS = GetProperties.getMeasurementUnit(dstFI); // error logging if (srcDataSize > 0 && dstDataSize > 0) { if (srcDataSize != dstDataSize) { error( conni, "Source data size " + srcDataSize + " Bytes and destination data size " + dstDataSize + " Bytes differ"); } } else { if (srcDataSize == 0 && dstDataSize > 0) error(conni, "Source data size is missing or zero"); if (dstDataSize == 0 && srcDataSize > 0) error(conni, "Destination data size is missing or zero"); } if (srcRU != null && dstRU != null && srcRU != dstRU) { error( conni, "Source rate unit " + srcRU.getName() + " and destination rate unit " + dstRU.getName() + " differ"); } if (srcMaxRateValue > 0 && dstMaxRateValue > 0) { if (srcMaxRateValue > dstMaxRateValue) { error( conni, "Maximum source data rate " + srcMaxRateValue + " is greater than maximum destination data rate " + dstMaxRateValue); } if (srcMinRateValue < dstMinRateValue) { error( conni, "Minimum source data rate " + srcMinRateValue + " is less than minimum destination data rate " + dstMinRateValue); } } else { if (srcRate != null || dstRate != null) { error(conni, "Missing input rate or output rate"); } } if (srcRateValue > 0 && dstRateValue > 0) { if (srcRateValue != dstRateValue) { error( conni, "Source data rate " + srcRateValue + " and destination data rate " + dstRateValue + " differ"); } } else { if (srcRateValue == 0 && dstRateValue > 0) error(conni, "Source data rate is missing or zero"); if (dstRateValue == 0 && srcRateValue > 0) error(conni, "Destination data rate is missing or zero"); } if (srcC != null && dstC != null) { if (srcC != dstC) { error( conni, "Source base type " + srcC.getName() + " and destination base type " + dstC.getName() + " differ"); } } else { if (srcC == null && dstC != null) error(conni, "Source base type is missing"); if (dstC == null && srcC != null) error(conni, "Destination base type is missing"); } if (srcS.length() > 0 && dstS.length() > 0) { if (!srcS.equalsIgnoreCase(dstS)) { error( conni, "Source measurement unit " + srcS + " and destination measurement unit " + dstS + " differ"); } } else { if (srcS.length() == 0 && dstS.length() > 0) error(conni, "Source measurement unit is missing"); if (dstS.length() == 0 && srcS.length() > 0) error(conni, "Destination measurement unit is missing"); } }