UNPKG

domotz-remote-pawn

Version:

Domotz Agent

108 lines (91 loc) 4.02 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz Ltd * * 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/>. **/ var _ = require('lodash'); var bonjourParser = require('./parsers/base_parser'); // Bonjour module use this options to initialize a mutlicast dns server // https://www.npmjs.com/package/multicast-dns const DEFAULT_OPTIONS = { host: '224.0.0.251', // N.B. Equivalent to ip port: 5353, type: 'udp4', interface: null, // Just for udp6 reuseAddr: true, // If another MDNS is on the system socket: null, // If you want create your own socket multicast: true, ttl: 255, loopback: true, // Set Multicast Loopback }; const BONJOUR_DISCOVERY_TIMEOUT = 20000; const BONJOUR_DISCOVERY_CYCLES_BEFORE_SERVICE_DELETE = 10; module.exports.factory = function (opts, resourceLocator) { var logger = resourceLocator.log.decorateLogs(); var ignoredServices = _.get(resourceLocator, 'configuration.settings.discovery_blacklist.bonjour.ignored_services', []); var ignoredPaths = _.get(resourceLocator, 'configuration.settings.discovery_blacklist.bonjour.ignored_paths', []); opts = opts || _.extend(DEFAULT_OPTIONS); var bonjour = resourceLocator.bonjour(opts); var ipConflict = resourceLocator.networkTools.ipConflictDetection; var working = true; var accumulator = require('./service_accumulator')._accumulator(BONJOUR_DISCOVERY_CYCLES_BEFORE_SERVICE_DELETE); bonjour._server.mdns.on('error', function (err) { logger.warn('BONJOUR - (mdns): Error in initializing server: %s', err.message); working = false; }); function discover(cb, resourceLocator) { var interfaceBidingStorage = resourceLocator.interfacesBindingStorage; var serviceFilter = resourceLocator.discovery.serviceFilter; var result = {}; if (!working) { logger.warn('BONJOUR - (mdns): No internal server active. Another MDNS daemon is running.'); cb({}); return; } var browser = bonjour.find({}, function onUp(s) { var entry = bonjourParser.parse(s, s.type); if (!entry) { logger.warn('Cannot extract IP v4 address from sample ' + s.addresses); return; } if (ipConflict.checkIfIpInConflict(entry.ip)) { logger.warn('Skip bonjour discovery for conflicting IP: %s', entry.ip); return; } var mac = interfaceBidingStorage.getMacFromIp(entry.ip); if (mac === undefined) { logger.warn('Cannot find MAC address for device with IP <%s>', entry.ip); return; } if (serviceFilter.isServiceIgnored(ignoredServices, entry)) { logger.debug('Ignoring service %s for device %s (%s)', entry.service, mac, entry.ip); return; } serviceFilter.ignorePaths(ignoredPaths, entry); if (!result[mac]) { result[mac] = { $: { mac: mac, ip: entry.ip } }; } result[mac][entry.service] = entry; delete entry.service; }); setTimeout(function () { browser.stop(); cb(accumulator(result)); //bonjour.destroy(); }, BONJOUR_DISCOVERY_TIMEOUT); } return { discover: discover, }; };