Skip to content

Commit 152613f

Browse files
authored
[ipcamera] Fix event streams crash when no source is specified. (openhab#18312)
* Fix regressions Signed-off-by: Matthew Skinner <[email protected]>
1 parent dcac0a4 commit 152613f

File tree

4 files changed

+34
-37
lines changed

4 files changed

+34
-37
lines changed

bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/InstarHandler.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,10 @@ public void alarmTriggered(String alarm) {
383383
public ArrayList<String> getLowPriorityRequests() {
384384
ArrayList<String> lowPriorityRequests = new ArrayList<>(7);
385385
lowPriorityRequests.add("/param.cgi?cmd=getaudioalarmattr");
386-
lowPriorityRequests.add("/cgi-bin/hi3510/param.cgi?cmd=getmdattr");
387-
if (ipCameraHandler.newInstarApi) {// old API cameras get a error 404 response to this
386+
if (ipCameraHandler.newInstarApi) {// old and new API cameras get a error 404 if sent the wrong one
388387
lowPriorityRequests.add("/param.cgi?cmd=getalarmattr");
388+
} else {
389+
lowPriorityRequests.add("/cgi-bin/hi3510/param.cgi?cmd=getmdattr");
389390
}
390391
lowPriorityRequests.add("/param.cgi?cmd=getinfrared");
391392
lowPriorityRequests.add("/param.cgi?cmd=getoverlayattr&-region=1");

bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/ReolinkHandler.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object ms
305305
ipCameraHandler.setChannelState(CHANNEL_WHITE_LED, OnOffType.ON);
306306
}
307307
break;
308+
case "/api.cgi?cmd=AudioAlarmPlay":
308309
case "/cgi-bin/api.cgi?cmd=Snap":
309310
break;
310311
case "/api.cgi?cmd=GetAiCfg":
@@ -322,7 +323,8 @@ public void channelRead(@Nullable ChannelHandlerContext ctx, @Nullable Object ms
322323
}
323324
break;
324325
default:
325-
if (!cutDownURL.startsWith("/cgi-bin/api.cgi?cmd=Set")) {// ignore responses from all Setxx commands
326+
if (!cutDownURL.startsWith("/cgi-bin/api.cgi?cmd=Set")
327+
|| !cutDownURL.startsWith("/api.cgi?cmd=Set")) {// ignore responses from all Setxx commands
326328
ipCameraHandler.logger.warn(
327329
"URL {} is not handled currently by the binding, please report this message",
328330
cutDownURL);

bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifCodec.java

-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ public void exceptionCaught(@Nullable ChannelHandlerContext ctx, @Nullable Throw
115115
@Override
116116
public void handlerRemoved(@Nullable ChannelHandlerContext ctx) {
117117
if (requestType == RequestType.PullMessages) {
118-
onvifConnection.lastPullMessageReceivedTimestamp = System.currentTimeMillis();
119118
onvifConnection.pullMessageRequests.decrementAndGet();
120119
}
121120
}

bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java

+28-33
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,9 @@ public enum RequestType {
141141
private IpCameraHandler ipCameraHandler;
142142
// Use/skip events even if camera support them. API cameras skip, as their own methods give better results.
143143
private boolean usingEvents = false;
144-
private int onvifEventServiceType = 0; // 0 = disabled, 1 = PullMessages, 2 = WSBaseSubscription
144+
private int onvifEventServiceType = 0; // 0 = auto detect, 1 = disabled, 2 = PullMessages, 3 = WSBaseSubscription
145145
public AtomicInteger pullMessageRequests = new AtomicInteger();
146146
private long createSubscriptionTimestamp;
147-
public long lastPullMessageReceivedTimestamp;
148147

149148
// These hold the cameras PTZ position in the range that the camera uses, ie
150149
// mine is -1 to +1
@@ -425,13 +424,18 @@ public void processReply(RequestType requestType, String message) {
425424

426425
private void setOnvifEventServiceType(boolean cameraSupportsPullPointSupport,
427426
boolean cameraSupportsSubscriptionPolicySupport) {
428-
if (cameraSupportsPullPointSupport && ipCameraHandler.cameraConfig.getOnvifEventServiceType() == 0
429-
|| ipCameraHandler.cameraConfig.getOnvifEventServiceType() == 2) {
430-
onvifEventServiceType = 1;
431-
} else if (cameraSupportsSubscriptionPolicySupport
432-
&& ipCameraHandler.cameraConfig.getOnvifEventServiceType() == 0
433-
|| ipCameraHandler.cameraConfig.getOnvifEventServiceType() == 3) {
427+
// 0 = auto detect, 1 = disabled, 2 = PullMessages, 3 = WSBaseSubscription
428+
if (cameraSupportsPullPointSupport && ipCameraHandler.cameraConfig.getOnvifEventServiceType() == 0) {
434429
onvifEventServiceType = 2;
430+
} else if (cameraSupportsSubscriptionPolicySupport
431+
&& ipCameraHandler.cameraConfig.getOnvifEventServiceType() == 0) {
432+
onvifEventServiceType = 3;
433+
} else if (ipCameraHandler.cameraConfig.getOnvifEventServiceType() == 0) {
434+
logger.warn(
435+
"Camera at {} could not auto detect the ONVIF event method the camera supports, try setting the configuration away from auto to remove this message by forcing an option.",
436+
ipAddress);
437+
} else {
438+
onvifEventServiceType = ipCameraHandler.cameraConfig.getOnvifEventServiceType();
435439
}
436440
}
437441

@@ -480,7 +484,7 @@ void setSubscriptionXAddr(String message) {
480484

481485
public void createSubscription() {
482486
if (!getEventsSupported()) {
483-
// ONVIF events are disabled or not supported.
487+
logger.debug("ONVIF events are disabled or not supported for camera at {}", ipAddress);
484488
return;
485489
}
486490

@@ -495,9 +499,9 @@ public void createSubscription() {
495499

496500
// Prefer PullPoint events over WSBaseSubscription because there is no way to check if a WSBaseSubscription is
497501
// already registered on the camera.
498-
if (onvifEventServiceType == 1) {
502+
if (onvifEventServiceType == 2) {
499503
sendOnvifRequest(RequestType.CreatePullPointSubscription, eventXAddr);
500-
} else if (onvifEventServiceType == 2) {
504+
} else if (onvifEventServiceType == 3) {
501505
sendOnvifRequest(RequestType.Subscribe, eventXAddr);
502506
}
503507
}
@@ -507,20 +511,20 @@ public void createSubscription() {
507511
* needed.
508512
*/
509513
public void checkAndRenewEventSubscription() {
510-
if (getEventsSupported()) {
511-
// If we get events via PullMessages check if a PullMessages request is running or we just received an
512-
// answer in the last second. If this is not the case create a new PullMessages subscription.
513-
if (onvifEventServiceType == 1 && pullMessageRequests.intValue() == 0
514-
&& System.currentTimeMillis() - lastPullMessageReceivedTimestamp > 1000) {
515-
logger.debug("The alarm stream was not running for camera {}, re-starting it now", ipAddress);
516-
createSubscription();
517-
} else if (!subscriptionXAddr.isEmpty()) {
518-
// Renew the active subscription.
519-
sendOnvifRequest(RequestType.Renew, subscriptionXAddr);
520-
} else {
514+
if (getEventsSupported() && onvifEventServiceType == 2) {
515+
if (subscriptionXAddr.isEmpty()) {
521516
// The camera claims to have event support, but no subscription was created yet. Try to create a new
522517
// subscription.
523518
createSubscription();
519+
} else if (pullMessageRequests.intValue() == 0) {
520+
// If we get events via PullMessages, check if a PullMessages request is running. Netty's
521+
// IdleStateHandler
522+
// will know if any request fails after a set time expires.
523+
sendOnvifRequest(RequestType.Renew, subscriptionXAddr);
524+
logger.debug("The alarm stream was not running for camera {}, re-starting it now", ipAddress);
525+
sendOnvifRequest(RequestType.PullMessages, subscriptionXAddr);
526+
} else {
527+
sendOnvifRequest(RequestType.Renew, subscriptionXAddr);
524528
}
525529
}
526530
}
@@ -828,16 +832,8 @@ public void eventReceived(String eventMessage) {
828832
Element topicElement = (Element) notificationMessageElement.getElementsByTagName("wsnt:Topic").item(0);
829833
String topic = topicElement.getFirstChild().getNodeValue().replace("tns1:", "");
830834

831-
String sourceName = "";
832-
String sourceValue = "";
833835
Element sourceElement = (Element) notificationMessageElement.getElementsByTagName("tt:Source").item(0);
834836

835-
if (sourceElement != null) {
836-
Element sourceItemElement = (Element) sourceElement.getElementsByTagName("tt:SimpleItem").item(0);
837-
sourceName = sourceItemElement.getAttributes().getNamedItem("Name").getNodeValue();
838-
sourceValue = sourceItemElement.getAttributes().getNamedItem("Value").getNodeValue();
839-
}
840-
841837
Element dataElement = (Element) notificationMessageElement.getElementsByTagName("tt:Data").item(0);
842838

843839
if (dataElement == null) {
@@ -850,8 +846,7 @@ public void eventReceived(String eventMessage) {
850846
String dataName = dataItemElement.getAttributes().getNamedItem("Name").getNodeValue();
851847
String dataValue = dataItemElement.getAttributes().getNamedItem("Value").getNodeValue();
852848

853-
logger.debug("ONVIF Event Topic: {}, Source name: {}, Source value: {}, Data name: {}, Data value: {}",
854-
topic, sourceName, sourceValue, dataName, dataValue);
849+
logger.debug("ONVIF Event Topic: {}, Data name: {}, Data value: {}", topic, dataName, dataValue);
855850
switch (topic) {
856851
case "RuleEngine/CellMotionDetector/Motion":
857852
if ("true".equals(dataValue)) {
@@ -1165,7 +1160,7 @@ public boolean isConnected() {
11651160
}
11661161

11671162
public boolean getEventsSupported() {
1168-
return onvifEventServiceType > 0;
1163+
return onvifEventServiceType > 1;// 0 = auto detect, 1 = disabled, 2 = PullMessages, 3 = WSBaseSubscription
11691164
}
11701165

11711166
public void setIsConnected(boolean isConnected) {

0 commit comments

Comments
 (0)