domotz-remote-pawn
Version:
Domotz Agent
141 lines (128 loc) • 5.24 kB
JavaScript
/** This file is part of Domotz Agent.
* Copyright (C) 2016 Domotz UK LLP
*
* Domotz Agent is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Domotz Agent is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>.
**/
/**
*
* Created by Iacopo Papalini <iacopo@domotz.com> on 19/03/2018.
*
*/
const PROTOCOL_NAME = 'onvif';
var url = require('url');
var onvifDiscoveryFactory = function (resourceLocator) {
'use strict';
var onvif = resourceLocator.onvif;
var isLoopbackLocation = resourceLocator.utils.web.isLoopbackUrl;
var myConsole = resourceLocator.log.decorateLogs();
var interfaceBidingStorage = resourceLocator.interfacesBindingStorage;
var discoverySender = resourceLocator.discoverySenderFactory(resourceLocator);
var discovery = onvif.Discovery;
var discoveryHost = resourceLocator.discovery.host;
var performUnicastDiscovery = function (discoverOnMulticastInterfaces) {
myConsole.info('Performing Onvif Unicast Discovery with default interface discovery set to: <%s>', discoverOnMulticastInterfaces);
var interfaces;
if (discoverOnMulticastInterfaces) {
interfaces = discoveryHost.getInterfacesList();
} else {
interfaces = discoveryHost.getUnicastInterfacesList();
}
for (var iface in interfaces) {
interfaces[iface].ipList.forEach(function (ipAddress) {
var isDeviceDenied = discoveryHost.isDeviceIPInL3DiscoveryDenyList(ipAddress);
if (isDeviceDenied) {
myConsole.debug('Onvif Discovery probe skipped for device IP = %s because in L3 Discovery Deny List', ipAddress);
} else {
myConsole.debug('Onvif Discovery probe sent for <%s>', ipAddress);
discovery.probe({ resolve: false, customDiscoveryAddress: ipAddress });
}
});
}
};
var discover = function (callback, errorCallback) {
if (resourceLocator.settingsManager.isBroadcastDiscoveryDisabled()) {
if (resourceLocator.settingsManager.isOnvifUnicastDiscoveryEnabled()) {
performUnicastDiscovery(true);
if (callback) {
callback();
}
return;
} else {
myConsole.info('Skipping Onvif Discovery');
if (callback) {
callback();
}
return;
}
}
try {
var multicastInterfacesList = discoveryHost.getMulticastInterfacesList();
for (var iface in multicastInterfacesList) {
myConsole.info('Broadcast discovery sent on multicast interface %s', iface);
discovery.probe({ resolve: false, device: iface });
}
performUnicastDiscovery(false);
} catch (error) {
if (errorCallback) {
errorCallback(error);
}
}
if (callback) {
callback();
}
};
discovery.on('error', function (err) {
// handle the error safely
myConsole.info('Discovery Error');
myConsole.info(err);
});
discovery.on('device', function (data) {
var mainAddress = url.parse(data.probeMatches.probeMatch.XAddrs.split(' ')[0]);
if (isLoopbackLocation(mainAddress.hostname)) {
myConsole.warn('Ignoring device that announces ONVIF hostname to <%s>', mainAddress.hostname);
return;
}
var mac = interfaceBidingStorage.getMacFromIp(mainAddress.hostname);
if (mac === undefined) {
myConsole.warn('Cannot find MAC address for device with IP <%s>', mainAddress.hostname);
return;
}
var splitSpaces = function (str) {
return (str || '').split(' ').filter(function (n) {
return n;
});
};
var onvifData = {
coordinates: {
host: mainAddress.hostname,
port: mainAddress.port,
addresses: splitSpaces(data.probeMatches.probeMatch.XAddrs),
},
types: splitSpaces(data.probeMatches.probeMatch.types),
scopes: splitSpaces(data.probeMatches.probeMatch.scopes),
};
_sendOnvifDataToEngine(mac, onvifData);
});
function _sendOnvifDataToEngine(mac, onvifData) {
discoverySender.sendAndCacheDiscoveryResult(mac, onvifData, {
getProtocolName: function () {
return PROTOCOL_NAME;
},
});
}
return {
discover: discover,
};
};
module.exports.factory = onvifDiscoveryFactory;