Java tutorial
/** * This file is part of JEMMA - http://jemma.energy-home.org * (C) Copyright 2013 Telecom Italia (http://www.telecomitalia.it) * * JEMMA is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License (LGPL) version 3 * or later as published by the Free Software Foundation, which accompanies * this distribution and is available at http://www.gnu.org/licenses/lgpl.html * * JEMMA 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 Lesser General Public License (LGPL) for more details. * */ package org.energy_home.jemma.javagal.layers.business.implementations; import org.energy_home.jemma.zgd.APSMessageListener; import org.energy_home.jemma.zgd.jaxb.APSMessageEvent; import org.energy_home.jemma.zgd.jaxb.Address; import org.energy_home.jemma.zgd.jaxb.Callback; import org.energy_home.jemma.zgd.jaxb.Filter; import org.energy_home.jemma.zgd.jaxb.Filter.AddressSpecification; import org.energy_home.jemma.zgd.jaxb.Filter.MessageSpecification; import org.energy_home.jemma.zgd.jaxb.Level; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.energy_home.jemma.javagal.layers.business.GalController; import org.energy_home.jemma.javagal.layers.object.CallbackEntry; /** * Manages received APS messages. When an APS indication is received it is * passed to this class' {@code APSMessageIndication} method. * * @author "Ing. Marco Nieddu <marco.nieddu@consoft.it> or <marco.niedducv@gmail.com> from Consoft Sistemi S.P.A.<http://www.consoft.it>, financed by EIT ICT Labs activity SecSES - Secure Energy Systems (activity id 13030)" * */ public class ApsManager { private final static Log logger = LogFactory.getLog(ApsManager.class); /** * The local {@link GalController} reference. */ GalController gal = null; /** * Creates a new instance with a Gal controller reference. * * @param _gal * a Gal controller reference. */ public ApsManager(GalController _gal) { gal = _gal; } /** * Processes the APS indication message trying to dispatch it to the right * destination. The {@link GalController} maintains a collection of * registered callbacks' listeners. This method verifies if a match exists * on that collection for the callback's filter, i.e. looks if one or more * destination(s) for that APS message is present. If it exists, sends the * APS message to all found destinations. * * @param message * the indication APSMessageEvent to process. */ public void APSMessageIndication(final APSMessageEvent message) { Thread thr = new Thread() { @Override public void run() { if (gal.getPropertiesManager().getDebugEnabled()) { logger.info("Aps Message Indication in process..."); } for (CallbackEntry ce : gal.getCallbacks()) { APSMessageListener apml = ce.getDestination(); Callback callback = ce.getCallback(); Filter filter = callback.getFilter(); if (filter.getLevelSpecification().getLevel().get(0).equals(Level.APS_LEVEL)) { if (filter.getMessageSpecification().size() > 0) { boolean messageSpecificationFound = false; for (MessageSpecification ms : filter.getMessageSpecification()) { if (ms.getAPSClusterIdentifier() == null) { messageSpecificationFound = true; // If match we can stop the search loop. break; } else if (ms.getAPSClusterIdentifier() == message.getClusterID()) { messageSpecificationFound = true; // If match we can stop the search loop. break; } } if (!messageSpecificationFound) { // If no Messaging Specification was found, // then this callback doesn't match and we // can jump to check the next one. continue; } } // Address Specification check. If there are at // least one address specification in the filter, // then we proceed to find a match, else if no // address specification is present we assume that // the check pass. if (filter.getAddressSpecification().size() > 0) { boolean addressingSpecificationFound = false; for (AddressSpecification as : filter.getAddressSpecification()) { // Source Address (Address Specification) Address assa = as.getNWKSourceAddress(); int asnsa = 0xFFFF; // If null, then we assume that all address // match for this filter, and so we leave // the initial value of 0xFFFF. if (assa != null) { asnsa = assa.getNetworkAddress(); } short assep = -1; if (as.getAPSSourceEndpoint() != null) assep = as.getAPSSourceEndpoint(); // Pass if the callback has a broadcast // Source Address if (asnsa != 0xFFFF) { // Source Address long msam = message.getSourceAddressMode().longValue(); Address msa = message.getSourceAddress(); if (msam == 0x01) { // Network address, NO source end // point int msna0x01 = msa.getNetworkAddress(); // Pass if the message has a // broadcast Source Address if (msna0x01 != 0xFFFF) { // Don't pass if they differs, // so we go ahead on the next // iteration in the for cycle if (asnsa != msna0x01) { continue; } } } else if (msam == 0x02) { // Network address, AND source end // point present. int msna0x02 = msa.getNetworkAddress(); short msep = message.getSourceEndpoint(); // Pass if the message has a // broadcast Source Address. if (msna0x02 != 0xFFFF) { // Don't pass if they differs, // so we go ahead on the // next iteration in for cycle. if (asnsa != msna0x02) { // Don't pass if they // differs, so we go ahead // on the next iteration in // the for cycle. continue; } else if (msep != 0xFF) { if (msep != assep) { // Don't pass if they // differs, so we go // ahead on the next // iteration in the for // cycle. continue; } } } } else if (msam == 0x03) { logger.info("AIA"); // ASK No ieee address defined in // the AddressSpecification // object. We do nothing since we // can't compare the values. } } // If reached this point, then a matching // Source Address is found for the current // AddressSpecification. So we can proceed // to check the Destination End Point. // Destination End Point (Address // Specification) if (as.getAPSDestinationEndpoint() == null) { addressingSpecificationFound = true; break; } else { short asdep = as.getAPSDestinationEndpoint(); // Pass if the callback has a broadcast // Destination End Point if (asdep != 0xFF) { long dam = message.getDestinationAddressMode(); // 0x00 and 0x01 Destination End // Point // not present if (dam > 0x01) { short mdep = message.getDestinationEndpoint(); // Pass if the message has a // broadcast Destination End // Point if (mdep != 0xFF) { // Don't pass if they // differs, // so we go ahead on the // next // iteration in the for // cycle if (asdep != mdep) { continue; } } } } } // If reached this point, then a matching // Destination End Point is also found for // the current AddressSpecification. This // means that a matching Addressing // Specification is found. We can stop here // the loop since one match it's enough. addressingSpecificationFound = true; break; } if (!addressingSpecificationFound) { // If no Addressing Specification was found, // then this callback doesn't match and we // can jump to check the next one. continue; } } // If this point is reached, then a matching // callback is found. Notify the message to its // destination. apml.notifyAPSMessage(message); // Add it to the list of already notified // destinations. } } } }; thr.setName("Thread APSMessageIndication(final APSMessageEvent message)"); thr.start(); } }