|
@@ -2,6 +2,7 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols;
|
|
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collection;
|
|
|
|
+import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
import java.util.LinkedList;
|
|
|
|
|
|
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
|
|
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
|
|
@@ -31,6 +32,11 @@ public class MQTT_protocol implements Protocol {
|
|
* Subscriber which subscribe to different Topics
|
|
* Subscriber which subscribe to different Topics
|
|
*/
|
|
*/
|
|
private LinkedList<Port> subs;
|
|
private LinkedList<Port> subs;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Topics subscribed by each Port
|
|
|
|
+ */
|
|
|
|
+ private HashMap<Port,LinkedList<String>> subbedTopics = new HashMap<Port,LinkedList<String>>();
|
|
|
|
|
|
/**
|
|
/**
|
|
* Devices that are Publisher and Subscriber and therefore send and receive
|
|
* Devices that are Publisher and Subscriber and therefore send and receive
|
|
@@ -85,11 +91,51 @@ public class MQTT_protocol implements Protocol {
|
|
*/
|
|
*/
|
|
if(port==broker){
|
|
if(port==broker){
|
|
//Broker should not send new packages, without new messages
|
|
//Broker should not send new packages, without new messages
|
|
- }else if(pubs.contains(port)){
|
|
|
|
|
|
+ }else if(subs.contains(port)||pubSubs.contains(port)){
|
|
|
|
+
|
|
|
|
+ //Subs can either subscribe to topics or unsubscribe
|
|
|
|
+ /**
|
|
|
|
+ * Topics, the SmartDevice is subscribed to
|
|
|
|
+ */
|
|
|
|
+ LinkedList<String> tops= subbedTopics.get(port);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Topic which should be subscribed or unsubscribed
|
|
|
|
+ */
|
|
|
|
+ String newTopic;
|
|
|
|
+ //Subsribe if no subscriptions so far or not subscribed to all, with a probability of70%
|
|
|
|
+ if(tops.size()==0||(tops.size()!=subbedTopics.size()&&Math.random()<0.7)){
|
|
|
|
+ //Forced Subscribe
|
|
|
|
+ newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
|
|
|
|
+ returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
|
|
|
|
+ timestep+=broker.getResponseTime();
|
|
|
|
+ returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
|
|
|
|
+ tops.add(newTopic);
|
|
|
|
+ }
|
|
|
|
+ else if(tops.size()==subbedTopics.size()){
|
|
|
|
+ //Forced Unsubscribe
|
|
|
|
+ newTopic = tops.get((int) Math.floor(Math.random()*tops.size()));
|
|
|
|
+ returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
|
|
|
|
+ timestep+=broker.getResponseTime();
|
|
|
|
+ returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBACK, timestep, broker, port));
|
|
|
|
+ tops.remove(newTopic);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(pubSubs.contains(port)&&Math.random()<0.3){
|
|
|
|
+ //When also Pub, publish sometimes
|
|
|
|
+ newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
|
|
|
|
+ returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "Topic:"+newTopic));
|
|
|
|
+ timestep+=broker.getResponseTime();
|
|
|
|
+ returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if(pubs.contains(port)||pubSubs.contains(port)&&Math.random()<0.3){
|
|
|
|
+ String newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
|
|
/**
|
|
/**
|
|
* Message to be published (Should be further specialized by a Sensor Device)
|
|
* Message to be published (Should be further specialized by a Sensor Device)
|
|
*/
|
|
*/
|
|
- String msg = "Topic: DoorState:"+(Math.random()<0.5?"true":"false");
|
|
|
|
|
|
+ String msg = "Topic:"+newTopic+":"+(Math.random()<0.5?"true":"false");
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, port, broker, msg));
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, port, broker, msg));
|
|
//Response
|
|
//Response
|
|
timestep+=broker.getResponseTime();
|
|
timestep+=broker.getResponseTime();
|
|
@@ -98,21 +144,19 @@ public class MQTT_protocol implements Protocol {
|
|
//Publish to Subscribers
|
|
//Publish to Subscribers
|
|
//Should be be improved to just notify Subs that are subscribed to the topic
|
|
//Should be be improved to just notify Subs that are subscribed to the topic
|
|
for(Port p:subs){
|
|
for(Port p:subs){
|
|
|
|
+ if(!subbedTopics.get(p).contains(newTopic))continue;//Skip unsubbed ports
|
|
timestep+=broker.getResponseTime();
|
|
timestep+=broker.getResponseTime();
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
|
|
}
|
|
}
|
|
for(Port p:pubSubs){
|
|
for(Port p:pubSubs){
|
|
|
|
+ if(!subbedTopics.get(p).contains(newTopic))continue;//skip unsubbed ports
|
|
timestep+=broker.getResponseTime();
|
|
timestep+=broker.getResponseTime();
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
|
|
returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
|
|
}
|
|
}
|
|
- }else if(subs.contains(port)){
|
|
|
|
- returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "Topic: DoorState"));
|
|
|
|
- timestep+=broker.getResponseTime();
|
|
|
|
- returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
|
|
|
|
}
|
|
}
|
|
- return null;
|
|
|
|
|
|
+ return returnPackets;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -162,12 +206,15 @@ public class MQTT_protocol implements Protocol {
|
|
return false;
|
|
return false;
|
|
case 1:
|
|
case 1:
|
|
pubSubs.add(device);
|
|
pubSubs.add(device);
|
|
|
|
+
|
|
|
|
+ subbedTopics.putIfAbsent(device, new LinkedList<String>());
|
|
break;
|
|
break;
|
|
case 2:
|
|
case 2:
|
|
pubs.add(device);
|
|
pubs.add(device);
|
|
break;
|
|
break;
|
|
case 3:
|
|
case 3:
|
|
subs.add(device);
|
|
subs.add(device);
|
|
|
|
+ subbedTopics.putIfAbsent(device, new LinkedList<String>());
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
// invalid role
|
|
// invalid role
|
|
@@ -191,6 +238,8 @@ public class MQTT_protocol implements Protocol {
|
|
removedDevice|=pubSubs.remove(device);
|
|
removedDevice|=pubSubs.remove(device);
|
|
removedDevice|=subs.remove(device);
|
|
removedDevice|=subs.remove(device);
|
|
removedDevice|=pubs.remove(device);
|
|
removedDevice|=pubs.remove(device);
|
|
|
|
+ //Remove Port from topics and clear its list
|
|
|
|
+ subbedTopics.remove(device).clear();
|
|
if(removedDevice && broker!=null){
|
|
if(removedDevice && broker!=null){
|
|
//If not the broker and device was removed -> disconnect
|
|
//If not the broker and device was removed -> disconnect
|
|
currentPackets.add(new MQTT_packet(MQTT_packet.DISCONNECT, currentPackets.size()/2, device, broker));
|
|
currentPackets.add(new MQTT_packet(MQTT_packet.DISCONNECT, currentPackets.size()/2, device, broker));
|