public WifiP2pConfig createFromParcel(Parcel in) { WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = in.readString(); config.wps = (WpsInfo) in.readParcelable(null); config.groupOwnerIntent = in.readInt(); config.persist = Persist.valueOf(in.readString()); return config; }
public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("\n address: ").append(deviceAddress); sbuf.append("\n wps: ").append(wps); sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent); sbuf.append("\n persist: ").append(persist.toString()); return sbuf.toString(); }
/** @author dduggan */ public class State implements IState, IRouting { static final long serialVersionUID = 0L; public static Logger log = Logger.getLogger(State.class.getCanonicalName()); protected NodeInfo info; public State(NodeInfo info) { super(); this.info = info; this.predecessor = null; this.successor = info; this.finger = new NodeInfo[NKEYS]; for (int i = 0; i < NKEYS; i++) { finger[i] = info; } } /* * Get the info for this DHT node. */ public NodeInfo getNodeInfo() { return info; } /* * Local table operations. */ private Persist.Table dict = Persist.newTable(); @SuppressWarnings("unused") private Persist.Table backup = Persist.newTable(); @SuppressWarnings("unused") private NodeInfo backupSucc = null; public synchronized String[] get(String k) { List<String> vl = dict.get(k); if (vl == null) { return null; } else { String[] va = new String[vl.size()]; return vl.toArray(va); } } public synchronized void add(String k, String v) { List<String> vl = dict.get(k); if (vl == null) { vl = new ArrayList<String>(); dict.put(k, vl); } vl.add(v); // TODO: broadcast an event to any listeners if (listeners.containsKey(k)) { broadcastAddition(k, v); } // DONE } public synchronized void delete(String k, String v) { List<String> vs = dict.get(k); if (vs != null) vs.remove(v); } public synchronized void clear() { dict.clear(); } /* * Operations for transferring state between predecessor and successor. */ /* * Successor: Extract the bindings from the successor node. */ public synchronized TableRep extractBindings(int predId) { return Persist.extractBindings(predId, info, successor, dict); } public synchronized TableRep extractBindings() { return Persist.extractBindings(info, successor, dict); } /* * Successor: Drop the bindings that are transferred to the predecessor. */ public synchronized void dropBindings(int predId) { Persist.dropBindings(dict, predId, getNodeInfo().id); } /* * Predecessor: Install the transferred bindings. */ public synchronized void installBindings(TableRep db) { dict = Persist.installBindings(dict, db); } /* * Predecessor: Back up bindings from the successor. */ public synchronized void backupBindings(TableRep db) { backup = Persist.backupBindings(db); // backupSucc = db.getSucc(); } public synchronized void backupSucc(TableRep db) { backupSucc = db.getSucc(); } /* * A never-used operation for storing state in a file. */ public synchronized void backup(String filename) throws IOException { Persist.save(info, successor, dict, filename); } public synchronized void reload(String filename) throws IOException { dict = Persist.load(filename); } public synchronized void display() { PrintWriter wr = new PrintWriter(System.out); Persist.display(dict, wr); } /* * Routing operations. */ private NodeInfo predecessor = null; private NodeInfo successor = null; private NodeInfo[] finger; public synchronized void setPred(NodeInfo pred) { predecessor = pred; } public NodeInfo getPred() { return predecessor; } public synchronized void setSucc(NodeInfo succ) { successor = succ; } public NodeInfo getSucc() { return successor; } public synchronized void setFinger(int i, NodeInfo info) { this.finger[i] = info; } public synchronized NodeInfo getFinger(int i) { return this.finger[i]; } public synchronized NodeInfo closestPrecedingFinger(int id) { /* * TODO: Get closest preceding finger for id, to continue search at that * node. Hint: See DHTBase.inInterval() */ for (int i = IRouting.NFINGERS; i > 0; i--) { int UB = finger[i].id % IRouting.NKEYS; int LB = finger[i - 1].id % IRouting.NKEYS; if (id == UB) return getFinger(i - 1); if (LB < UB) { UB = (UB - LB); LB = (id - LB); if (0 <= LB && LB < UB) { // TODO, or (0 <= LB && LB < UB) return getFinger(i - 1); } } else if (UB < LB) { UB = (UB + (IRouting.NKEYS - LB)) % IRouting.NKEYS; LB = (id + (IRouting.NKEYS - LB)) % IRouting.NKEYS; if (0 <= LB && LB < UB) { // TODO, or (0 <= LB && LB < UB) return getFinger(i - 1); } } } return this.info; } public synchronized void routes() { PrintWriter wr = new PrintWriter(System.out); wr.println("Predecessor: " + predecessor); wr.println("Successor : " + successor); wr.println("Fingers:"); wr.printf("%7s %3s %s\n", "Formula", "Key", "Succ"); wr.printf("%7s %3s %s\n", "-------", "---", "----"); for (int i = 0, exp = 1; i < IRouting.NFINGERS; i++, exp = 2 * exp) { wr.printf( " %2d+2^%1d %3d [id=%2d,uri=%s]%n", info.id, i, (info.id + exp) % IRouting.NKEYS, finger[i].id, finger[i].addr); } wr.flush(); } /* * Used to prevent a race condition in the join protocol. */ public static enum JoinState { NOT_JOINED, JOINING, JOINED } private JoinState joinState = JoinState.NOT_JOINED; private Lock joinStateLock = new ReentrantLock(); private Condition joined = joinStateLock.newCondition(); public void startJoin() { joinStateLock.lock(); try { joinState = JoinState.JOINING; } finally { joinStateLock.unlock(); } } public void joinCheck() { // Called by any operations that should block during join protocol. // Currently that is getPred() (for the case where we are joining a // single-node network). joinStateLock.lock(); try { while (joinState == JoinState.JOINING) { joined.await(); } } catch (InterruptedException e) { log.info("Join check loop was interrupted."); } finally { joinStateLock.unlock(); } } public void finishJoin() { joinStateLock.lock(); try { joinState = JoinState.JOINED; joined.signalAll(); } finally { joinStateLock.unlock(); } } /* * Server-side listeners for new bindings. */ private Map<String, SseBroadcaster> listeners = new HashMap<String, SseBroadcaster>(); private Map<Integer, Map<String, EventOutput>> outputs = new HashMap<Integer, Map<String, EventOutput>>(); @Override public void addListener(int id, String key, EventOutput os) { // TODO Auto-generated method stub if (!listeners.containsKey(key)) { listeners.put(key, new SseBroadcaster()); } if (!outputs.containsKey(id)) { outputs.put(id, new HashMap<String, EventOutput>()); } listeners.get(key).add(os); // Register OS outputs.get(id).put(key, os); // Prepare for sending message // Done } public void removeListener(int id, String key) { // TODO Close the event output stream. if (outputs.containsKey(id)) { EventOutput oput = outputs.get(id).remove(key); if (oput != null) { try { oput.close(); } catch (IOException e) { System.out.println("State.java: Line 321 error"); } } } else { // if SseBroadcaster bdcast = listeners.remove(key); if (bdcast != null) // Check if there is residue EventOutput in the // broadcaster { bdcast.closeAll(); } } // Done } private void broadcastAddition(String key, String value) { // TODO broadcast an added binding (use IDHTNode.NEW_BINDING_EVENT for // event name). /* the real meat of this assignment */ OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder(); OutboundEvent event = eventBuilder .name(IDHTNode.NEW_BINDING_EVENT) .mediaType(MediaType.TEXT_PLAIN_TYPE) .data(String.class, value) .build(); // System.out.println("\n" + key + " " + value); if (listeners.containsKey(key)) { // System.out.println("\ntrue"); listeners.get(key).broadcast(event); } } /* * Client-side callbacks for new binding notifications. */ private Map<String, EventSource> callbacks = new HashMap<String, EventSource>(); public void addCallback(String key, EventSource is) { removeCallback(key); callbacks.put(key, is); } public void removeCallback(String key) { // TODO remove an existing callback (if any) for bindings on key. // Be sure to close the event stream from the broadcaster. EventSource es = callbacks.remove(key); if (es != null) { es.close(); } // Done } public void listCallbacks() { PrintWriter wr = new PrintWriter(System.out); if (callbacks.isEmpty()) { wr.println("No listeners defined."); } else { wr.println("Listeners defined for:"); for (Entry<String, EventSource> entry : callbacks.entrySet()) { if (entry.getValue().isOpen()) { wr.println(" " + entry.getKey()); } else { wr.println(" " + entry.getKey() + " (closed)"); callbacks.remove(entry.getKey()); } } } wr.flush(); } }
public synchronized void display() { PrintWriter wr = new PrintWriter(System.out); Persist.display(dict, wr); }
public synchronized void reload(String filename) throws IOException { dict = Persist.load(filename); }
/* * A never-used operation for storing state in a file. */ public synchronized void backup(String filename) throws IOException { Persist.save(info, successor, dict, filename); }
/* * Predecessor: Back up bindings from the successor. */ public synchronized void backupBindings(TableRep db) { backup = Persist.backupBindings(db); // backupSucc = db.getSucc(); }
/* * Predecessor: Install the transferred bindings. */ public synchronized void installBindings(TableRep db) { dict = Persist.installBindings(dict, db); }
/* * Successor: Drop the bindings that are transferred to the predecessor. */ public synchronized void dropBindings(int predId) { Persist.dropBindings(dict, predId, getNodeInfo().id); }
public synchronized TableRep extractBindings() { return Persist.extractBindings(info, successor, dict); }
public String write() { persist.doIt(sb); return sb.toString(); }
/** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(deviceAddress); dest.writeParcelable(wps, flags); dest.writeInt(groupOwnerIntent); dest.writeString(persist.name()); }