📄 onewireserver.java
字号:
sc.writeDevice(state); complain(LOG_WARNING, CH_ONEWIRE, "Restored state for " + address + ": " + ss); } catch ( OneWireException ex ) { complain(LOG_ERR, CH_ONEWIRE, "Failed to restore switch state (" + address + "), cause:", ex); } catch ( InterruptedException iex ) { complain(LOG_ERR, CH_ONEWIRE, "Failed to restore switch state (" + address + "), cause:", iex); } finally { lock.release(lockToken); } } } Map address2device = (Map)path2device.get(e2.path); if ( address2device == null ) { address2device = new TreeMap(); // I wish the OWPath was Comparable, then it would have made a // nice sorted map... path2device.put(e2.path, address2device); } DeviceContainer dc = createContainer(owc); address2device.put(e.address, dc); this.address2device.put(e.address, dc); for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) { OneWireContainerListener l = (OneWireContainerListener)i.next(); l.deviceArrived(address, owc.getName()); } } private DeviceContainer createContainer(OneWireContainer owc) { // Let's see what kind of a device we have... if ( owc instanceof TemperatureContainer ) { return new OneWireTemperatureContainer(owc); } else if ( (owc instanceof SwitchContainer) && !("DS2409".equals(owc.getName())) ) { return new OneWireSwitchContainer(owc); } else { // This is too deep down the stack, and we can't afford to throw // an exception. Let's create a generic container and let the // callers figure the rest out. complain(LOG_NOTICE, CH_ONEWIRE, "createContainer(): don't know how to handle " + owc + ", generic container created"); return new OneWireDeviceContainer(owc); } } public void networkDeparture(OneWireNetworkEvent e) { // The only valid element here is the address for ( Iterator pi = path2device.keySet().iterator(); pi.hasNext(); ) { OWPath path = (OWPath)pi.next(); Map address2device = (Map)path2device.get(path); Object owc = address2device.get(e.address); if ( owc != null ) { // O! This is the one address2device.remove(e.address); this.address2device.remove(e.address); if ( address2device.isEmpty() ) { // There are no more devices on this path, so there's no // need to open it at all complain(LOG_INFO, CH_ONEWIRE, "Path doesn't contain any devices, removed: " + path); pi.remove(); } // We don't need the device state either, lest it gets // cached and interferes with the subsequent reads stateMap.remove(e.address); for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) { OneWireContainerListener l = (OneWireContainerListener)i.next(); l.deviceDeparted(e.address); } // We need to remove just one device, so there's no sense to // continue the iterator return; } } // The device wasn't found??? complain(LOG_WARNING, CH_ONEWIRE, "Got the departure notification before arrival notification for " + e.address); } public void networkFault(OneWireNetworkEvent e, String message) { for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) { OneWireContainerListener l = (OneWireContainerListener)i.next(); l.deviceFault(e.address, message); } } public Iterator iterator() { return address2device.keySet().iterator(); } public DeviceContainer getDeviceContainer(String address) { return (DeviceContainer)address2device.get(address); } public OWPath getDevicePath(String address) { for ( Iterator i = path2device.keySet().iterator(); i.hasNext(); ) { OWPath path = (OWPath)i.next(); Map address2device = (Map)path2device.get(path); if ( address2device.containsKey(address) ) { return path; } } throw new NoSuchElementException("No path found for '" + address + "'"); } protected class SwitchState { boolean smart = false; boolean state[] = { false, false }; public String toString() { String result = "[" + (smart ? "smart" : "dumb"); result += "]["; for ( int idx = 0; idx < state.length; idx++ ) { if ( idx != 0 ) { result += ","; } result += state[idx]; } result += "]"; return result; } } protected class OneWireDeviceContainer extends DeviceContainer { public final OneWireContainer container; public OneWireDeviceContainer(OneWireContainer container) { if ( container == null ) { throw new IllegalArgumentException("Container can't be null"); } this.container = container; } public String toString() { return container.toString(); } } protected class OneWireTemperatureContainer extends OneWireDeviceContainer implements net.sf.dz.daemon.onewire.TemperatureContainer { OneWireTemperatureContainer(OneWireContainer container) { super(container); } } protected class OneWireSwitchContainer extends OneWireDeviceContainer implements net.sf.dz.daemon.onewire.SwitchContainer { private int channelCount = 0; OneWireSwitchContainer(OneWireContainer container) { super(container); } public synchronized int getChannelCount() { if ( channelCount == 0 ) { // This means that we haven't read the device yet Object lockToken = null; RWLock lock = null; String address = container.getAddressAsString(); SwitchContainer sc = (SwitchContainer)container; try { long start = System.currentTimeMillis(); lock = getLock(); lockToken = lock.getWriteLock(); long gotLock = System.currentTimeMillis(); getDevicePath(address).open(); byte state[] = sc.readDevice(); channelCount = sc.getNumberChannels(state); long now = System.currentTimeMillis(); complain(LOG_INFO, CH_LOCK, address + " has " + channelCount + " channel[s], took us " + (now - start) + "ms to figure out (" + (gotLock - start) + " to get the lock, " + (now - gotLock) + " to retrieve)"); } catch ( Throwable t ) { complain(LOG_WARNING, CH_ONEWIRE, address + ": can't retrieve channel count (assuming 2):", t); channelCount = 2; } finally { if ( lock != null ) { lock.release(lockToken); } } } return channelCount; } public boolean read(int channel) throws IOException { Object lockToken = null; RWLock lock = null; SwitchContainer sc = (SwitchContainer)container; String address = container.getAddressAsString(); long start = System.currentTimeMillis(); try { lock = getLock(); lockToken = lock.getWriteLock(); complain(LOG_DEBUG, CH_LOCK, "got lock in " + (System.currentTimeMillis() - start) + "ms"); start = System.currentTimeMillis(); getDevicePath(address).open(); byte state[] = sc.readDevice(); complain(LOG_DEBUG, CH_ONEWIRE, "readDevice: " + (System.currentTimeMillis() - start)); boolean smart = sc.hasSmartOn(); return sc.getLatchState(channel, state); } catch ( Throwable t ) { IOException secondary = new IOException("Unable to read " + container); secondary.initCause(t); throw secondary; } finally { if ( lock != null ) { lock.release(lockToken); } complain(LOG_DEBUG, CH_LOCK, "complete in " + (System.currentTimeMillis() - start) + "ms"); } } public void write(int channel, boolean value) throws IOException { Object lockToken = null; RWLock lock = null; SwitchContainer sc = (SwitchContainer)container; String address = container.getAddressAsString(); long start = System.currentTimeMillis(); try { lock = getLock(); lockToken = lock.getWriteLock(); complain(LOG_DEBUG, CH_LOCK, "got lock in " + (System.currentTimeMillis() - start) + "ms"); start = System.currentTimeMillis(); getDevicePath(address).open(); byte state[] = sc.readDevice(); complain(LOG_DEBUG, CH_ONEWIRE, "readDevice: " + (System.currentTimeMillis() - start)); boolean smart = sc.hasSmartOn(); sc.setLatchState(channel, value, smart, state); sc.writeDevice(state); state = sc.readDevice(); if ( value == sc.getLatchState(channel, state) ) { return; } else { complain(LOG_ERR, CH_ONEWIRE, "Failed to write " + container); } } catch ( Throwable t ) { IOException secondary = new IOException("Unable to write " + container); secondary.initCause(t); throw secondary; } finally { if ( lock != null ) { lock.release(lockToken); } complain(LOG_DEBUG, CH_LOCK, "complete in " + (System.currentTimeMillis() - start) + "ms"); } } public void reset() throws IOException { // VT: FIXME: Can't afford to get the lock to improve latency - // it will deadlock. In order to fix that, RWLock has to be // modified to take multiple calls from the same thread into // account. for ( int channel = 0; channel < getChannelCount(); channel++ ) { write(channel, false); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -