package freenet.clients.http.wizardsteps; import freenet.config.Config; import freenet.config.ConfigException; import freenet.config.InvalidConfigValueException; import freenet.node.NodeClientCore; import freenet.pluginmanager.FredPluginBandwidthIndicator; import freenet.support.HTMLNode; import freenet.support.Logger; /** * Utility class used by bandwidth steps to detect and set bandwidth, and set the wizard completion flag. */ public abstract class BandwidthManipulator { protected final NodeClientCore core; protected final Config config; public BandwidthManipulator(NodeClientCore core, Config config) { this.config = config; this.core = core; } /** * Sets the selected limit type to the given limit. * @param limit To parse limit from. Can include SI or IEC units, but not /s. * @param setOutputLimit If true, output limit is set. If false, input limit is set. * @throws freenet.config.InvalidConfigValueException If the value is negative, a number cannot be parsed from it, or the value is too low to be usable. * @see freenet.node.Node#minimumBandwidth */ protected void setBandwidthLimit (String limit, boolean setOutputLimit) throws InvalidConfigValueException { String limitType = setOutputLimit ? "outputBandwidthLimit" : "inputBandwidthLimit"; try { config.get("node").set(limitType, limit); Logger.normal(this, "The " + limitType + " has been set to " + limit); } catch (ConfigException e) { if (e instanceof InvalidConfigValueException) { //Limit was not readable. throw (InvalidConfigValueException)e; } Logger.error(this, "Should not happen, please report!" + e, e); } } /** * Creates a titled infobox for a bandwidth setting error. * * @param parent Node to attach warning to. * @param helper Helper to create infobox. * @param message Message to display in the infobox body. * * @return infobox node with the message added. */ protected HTMLNode parseErrorBox(HTMLNode parent, PageHelper helper, String message) { HTMLNode infoBox = helper.getInfobox("infobox-warning", WizardL10n.l10n("bandwidthErrorSettingTitle"), parent, null, false); infoBox.addChild("p", message); return infoBox; } protected BandwidthLimit getCurrentBandwidthLimitsOrNull() { if (!config.get("node").getOption("outputBandwidthLimit").isDefault()) { return new BandwidthLimit(core.node.getInputBandwidthLimit(), core.node.getOutputBandwidthLimit(), "bandwidthCurrent", false); } return null; } /** * Attempts to detect upstream and downstream bandwidth limits. * @return Upstream and downstream bandwidth in bytes per second. If a limit is set to -1, it is unavailable or * nonsensically low. In case of error, both values are set to: * -2 if the upstream bandwidth setting has already been configured. * -3 if the UPnP plugin is not loaded or done starting up. */ protected BandwidthLimit detectBandwidthLimits() { FredPluginBandwidthIndicator bwIndicator = core.node.ipDetector.getBandwidthIndicator(); if (bwIndicator == null) { Logger.normal(this, "The node does not have a bandwidthIndicator."); return new BandwidthLimit(-3, -3, "bandwidthDetected", false); } int downstreamBits = bwIndicator.getDownstreamMaxBitRate(); int upstreamBits = bwIndicator.getUpstramMaxBitRate(); Logger.normal(this, "bandwidthIndicator reports downstream " + downstreamBits + " bits/s and upstream "+upstreamBits+" bits/s."); int downstreamBytes, upstreamBytes; //For readability, in bits. final int KiB = 8192; if (downstreamBits < 0) { //Reported unavailable. downstreamBytes = -1; } else if (downstreamBits < 8*KiB) { //Nonsensically slow. System.err.println("Detected downstream of "+downstreamBits+" bits/s is nonsensically slow, ignoring."); downstreamBytes = -1; } else { downstreamBytes = downstreamBits/8; } if (upstreamBits < 0) { //Reported unavailable.. upstreamBytes = -1; } else if (upstreamBits < KiB) { //Nonsensically slow. System.err.println("Detected upstream of "+upstreamBits+" bits/s is nonsensically slow, ignoring."); upstreamBytes = -1; } else { upstreamBytes = upstreamBits/8; } return new BandwidthLimit(downstreamBytes, upstreamBytes, "bandwidthDetected", false); } protected void setWizardComplete() { //Set wizard completion flag try { config.get("fproxy").set("hasCompletedWizard", true); config.store(); } catch (ConfigException e) { //TODO: Is there anything that can reasonably be done about this? What kind of failures could occur? //TODO: Is logging and continuing a reasonable behavior? Logger.error(this, e.getMessage(), e); } } }