igmp proxy app
Change-Id: If053dc39b611a6176b1d59004a480d65bfac9091
diff --git a/src/main/java/org/opencord/igmpproxy/StateMachine.java b/src/main/java/org/opencord/igmpproxy/StateMachine.java
new file mode 100644
index 0000000..6c12877
--- /dev/null
+++ b/src/main/java/org/opencord/igmpproxy/StateMachine.java
@@ -0,0 +1,97 @@
+package org.opencord.igmpproxy;
+
+import com.google.common.collect.Maps;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.net.DeviceId;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * State machine for whole IGMP process. The state machine is implemented on
+ * RFC 2236 "6. Host State Diagram".
+ */
+public final class StateMachine {
+ private StateMachine() {
+
+ }
+ private static Map<String, SingleStateMachine> map = Maps.newConcurrentMap();
+
+ private static String getId(DeviceId devId, Ip4Address groupIp) {
+ return devId.toString() + "Group" + groupIp.toString();
+ }
+
+ private static SingleStateMachine get(DeviceId devId, Ip4Address groupIp) {
+ String id = getId(devId, groupIp);
+ return map.get(id);
+ }
+
+ public static void destorySingle(DeviceId devId, Ip4Address groupIp) {
+ SingleStateMachine machine = get(devId, groupIp);
+ if (null == machine) {
+ return;
+ }
+ machine.cancelTimer();
+ map.remove(getId(devId, groupIp));
+ }
+
+ public static boolean join(DeviceId devId, Ip4Address groupIp, Ip4Address srcIP) {
+ SingleStateMachine machine = get(devId, groupIp);
+ if (null == machine) {
+ machine = new SingleStateMachine(devId, groupIp, srcIP);
+ map.put(getId(devId, groupIp), machine);
+ machine.join();
+ return true;
+ }
+ machine.increaseCounter();
+ return false;
+ }
+
+ public static boolean leave(DeviceId devId, Ip4Address groupIp) {
+ SingleStateMachine machine = get(devId, groupIp);
+ if (null == machine) {
+ return false;
+ }
+ machine.decreaseCounter();
+
+ if (machine.getCounter() == 0) {
+ machine.leave();
+ destorySingle(devId, groupIp);
+ return true;
+ }
+ return false;
+ }
+
+ static void specialQuery(DeviceId devId, Ip4Address groupIp, int maxResp) {
+ SingleStateMachine machine = get(devId, groupIp);
+ if (null == machine) {
+ return;
+ }
+ machine.query(maxResp);
+ }
+
+ static void generalQuery(DeviceId devId, int maxResp) {
+ for (Map.Entry<String, SingleStateMachine> entry : map.entrySet()) {
+ SingleStateMachine machine = entry.getValue();
+ if (devId.equals(machine.getDeviceId())) {
+ machine.query(maxResp);
+ }
+ }
+ }
+
+ public static Set<Map.Entry<String, SingleStateMachine>> entrySet() {
+ return map.entrySet();
+ }
+
+ public static void timeOut(DeviceId devId, Ip4Address groupIp) {
+ SingleStateMachine machine = get(devId, groupIp);
+ if (null == machine) {
+ return;
+ }
+ machine.timeOut();
+ }
+
+ public static void clearMap() {
+ map.clear();
+ }
+
+}