blob: 6c1287740856eecf2de45a85f29e04bee97c794b [file] [log] [blame]
ke han81a38b92017-03-10 18:41:44 +08001package org.opencord.igmpproxy;
2
3import com.google.common.collect.Maps;
4import org.onlab.packet.Ip4Address;
5import org.onosproject.net.DeviceId;
6import java.util.Map;
7import java.util.Set;
8
9/**
10 * State machine for whole IGMP process. The state machine is implemented on
11 * RFC 2236 "6. Host State Diagram".
12 */
13public final class StateMachine {
14 private StateMachine() {
15
16 }
17 private static Map<String, SingleStateMachine> map = Maps.newConcurrentMap();
18
19 private static String getId(DeviceId devId, Ip4Address groupIp) {
20 return devId.toString() + "Group" + groupIp.toString();
21 }
22
23 private static SingleStateMachine get(DeviceId devId, Ip4Address groupIp) {
24 String id = getId(devId, groupIp);
25 return map.get(id);
26 }
27
28 public static void destorySingle(DeviceId devId, Ip4Address groupIp) {
29 SingleStateMachine machine = get(devId, groupIp);
30 if (null == machine) {
31 return;
32 }
33 machine.cancelTimer();
34 map.remove(getId(devId, groupIp));
35 }
36
37 public static boolean join(DeviceId devId, Ip4Address groupIp, Ip4Address srcIP) {
38 SingleStateMachine machine = get(devId, groupIp);
39 if (null == machine) {
40 machine = new SingleStateMachine(devId, groupIp, srcIP);
41 map.put(getId(devId, groupIp), machine);
42 machine.join();
43 return true;
44 }
45 machine.increaseCounter();
46 return false;
47 }
48
49 public static boolean leave(DeviceId devId, Ip4Address groupIp) {
50 SingleStateMachine machine = get(devId, groupIp);
51 if (null == machine) {
52 return false;
53 }
54 machine.decreaseCounter();
55
56 if (machine.getCounter() == 0) {
57 machine.leave();
58 destorySingle(devId, groupIp);
59 return true;
60 }
61 return false;
62 }
63
64 static void specialQuery(DeviceId devId, Ip4Address groupIp, int maxResp) {
65 SingleStateMachine machine = get(devId, groupIp);
66 if (null == machine) {
67 return;
68 }
69 machine.query(maxResp);
70 }
71
72 static void generalQuery(DeviceId devId, int maxResp) {
73 for (Map.Entry<String, SingleStateMachine> entry : map.entrySet()) {
74 SingleStateMachine machine = entry.getValue();
75 if (devId.equals(machine.getDeviceId())) {
76 machine.query(maxResp);
77 }
78 }
79 }
80
81 public static Set<Map.Entry<String, SingleStateMachine>> entrySet() {
82 return map.entrySet();
83 }
84
85 public static void timeOut(DeviceId devId, Ip4Address groupIp) {
86 SingleStateMachine machine = get(devId, groupIp);
87 if (null == machine) {
88 return;
89 }
90 machine.timeOut();
91 }
92
93 public static void clearMap() {
94 map.clear();
95 }
96
97}