1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.model.gena;
17
18 import org.fourthline.cling.model.Location;
19 import org.fourthline.cling.model.Namespace;
20 import org.fourthline.cling.model.NetworkAddress;
21 import org.fourthline.cling.model.message.UpnpResponse;
22 import org.fourthline.cling.model.meta.RemoteService;
23 import org.fourthline.cling.model.state.StateVariableValue;
24 import org.fourthline.cling.model.types.UnsignedIntegerFourBytes;
25 import org.fourthline.cling.model.UnsupportedDataException;
26
27 import java.beans.PropertyChangeSupport;
28 import java.net.URL;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.List;
32
33
34
35
36
37
38
39
40
41
42 public abstract class RemoteGENASubscription extends GENASubscription<RemoteService> {
43
44 protected PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
45
46 protected RemoteGENASubscription(RemoteService service,
47 int requestedDurationSeconds) {
48 super(service, requestedDurationSeconds);
49 }
50
51 synchronized public URL getEventSubscriptionURL() {
52 return getService().getDevice().normalizeURI(
53 getService().getEventSubscriptionURI()
54 );
55 }
56
57 synchronized public List<URL> getEventCallbackURLs(List<NetworkAddress> activeStreamServers, Namespace namespace) {
58 List<URL> callbackURLs = new ArrayList<>();
59 for (NetworkAddress activeStreamServer : activeStreamServers) {
60 callbackURLs.add(
61 new Location(
62 activeStreamServer,
63 namespace.getEventCallbackPathString(getService())
64 ).getURL());
65 }
66 return callbackURLs;
67 }
68
69
70
71
72
73
74 synchronized public void establish() {
75 established();
76 }
77
78 synchronized public void fail(UpnpResponse responseStatus) {
79 failed(responseStatus);
80 }
81
82 synchronized public void end(CancelReason reason, UpnpResponse response) {
83 ended(reason, response);
84 }
85
86 synchronized public void receive(UnsignedIntegerFourBytes sequence, Collection<StateVariableValue> newValues) {
87
88 if (this.currentSequence != null) {
89
90
91 if (this.currentSequence.getValue().equals(this.currentSequence.getBits().getMaxValue()) && sequence.getValue() == 1) {
92 System.err.println("TODO: HANDLE ROLLOVER");
93 return;
94 }
95
96 if (this.currentSequence.getValue() >= sequence.getValue()) {
97 return;
98 }
99
100 int difference;
101 long expectedValue = currentSequence.getValue() + 1;
102 if ((difference = (int) (sequence.getValue() - expectedValue)) != 0) {
103 eventsMissed(difference);
104 }
105
106 }
107
108 this.currentSequence = sequence;
109
110 for (StateVariableValue newValue : newValues) {
111 currentValues.put(newValue.getStateVariable().getName(), newValue);
112 }
113
114 eventReceived();
115 }
116
117 public abstract void invalidMessage(UnsupportedDataException ex);
118
119 public abstract void failed(UpnpResponse responseStatus);
120
121 public abstract void ended(CancelReason reason, UpnpResponse responseStatus);
122
123 public abstract void eventsMissed(int numberOfMissedEvents);
124
125 @Override
126 public String toString() {
127 return "(SID: " + getSubscriptionId() + ") " + getService();
128 }
129 }