/** * Copyright (c) 2011, SOCIETIES Consortium (WATERFORD INSTITUTE OF TECHNOLOGY (TSSG), HERIOT-WATT UNIVERSITY (HWU), SOLUTA.NET * (SN), GERMAN AEROSPACE CENTRE (Deutsches Zentrum fuer Luft- und Raumfahrt e.V.) (DLR), Zavod za varnostne tehnologije * informacijske družbe in elektronsko poslovanje (SETCCE), INSTITUTE OF COMMUNICATION AND COMPUTER SYSTEMS (ICCS), LAKE * COMMUNICATIONS (LAKE), INTEL PERFORMANCE LEARNING SOLUTIONS LTD (INTEL), PORTUGAL TELECOM INOVAÇÃO, SA (PTIN), IBM Corp., * INSTITUT TELECOM (ITSUD), AMITEC DIACHYTI EFYIA PLIROFORIKI KAI EPIKINONIES ETERIA PERIORISMENIS EFTHINIS (AMITEC), TELECOM * ITALIA S.p.a.(TI), TRIALOG (TRIALOG), Stiftelsen SINTEF (SINTEF), NEC EUROPE LTD (NEC)) * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.societies.css.devicemgmt.devicemanager.impl; import java.util.ArrayList; import java.util.Dictionary; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import org.apache.commons.collections.BidiMap; import org.apache.commons.collections.bidimap.DualHashBidiMap; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.societies.api.comm.xmpp.interfaces.ICommManager; import org.societies.api.css.devicemgmt.IDevice; import org.societies.api.css.devicemgmt.model.DeviceMgmtConstants; import org.societies.api.identity.IIdentity; import org.societies.api.identity.IIdentityManager; import org.societies.api.identity.INetworkNode; import org.societies.api.internal.css.devicemgmt.IDeviceManager; import org.societies.api.internal.css.devicemgmt.comm.DmCommManager; import org.societies.api.internal.css.devicemgmt.model.DeviceCommonInfo; import org.springframework.osgi.context.BundleContextAware; //ADD BJB 31 08 2012 import org.societies.api.schema.servicelifecycle.model.Service; import org.societies.api.schema.servicelifecycle.model.ServiceType; //END BJB public class DeviceManager implements IDeviceManager, BundleContextAware { private static Logger LOG = LoggerFactory.getLogger(DeviceManager.class); private Map<String, DeviceImpl> deviceInstanceContainer; private final Map<String, Map<String, DeviceImpl>> deviceFamilyContainer; private final Map<String, ServiceRegistration> serviceRegistrationConatainer; private DeviceImpl deviceImpl; private Map<String, String[]> deviceServiceNamesContainer; public static BundleContext bundleContext; private BidiMap deviceIdBindingTable; private IIdentityManager idManager; private ICommManager commManager; private INetworkNode nodeId = null; // BJB 10/09/2012: Change Dictionary<String, String> -> Dictionary<String, Object> private Dictionary<String, Object> properties; // END private ServiceRegistration registration; private DmCommManager deviceCommManager; // BJB 10/09/2012 // add const for new properties attached to the IDevice osgi service public static final String SERVICE_PROVIDER = "ServiceProvider"; public static final String TARGET_PLATFORM = "TargetPlatform"; // END public DeviceManager() { deviceFamilyContainer = new HashMap<String, Map<String, DeviceImpl>>(); deviceServiceNamesContainer = new HashMap<String, String[]>(); // TODO Fill this table deviceIdBindingTable = new DualHashBidiMap(); serviceRegistrationConatainer = new HashMap<String, ServiceRegistration>(); } public DmCommManager getDeviceCommManager() { return deviceCommManager; } public void setDeviceCommManager(DmCommManager deviceCommManager) { this.deviceCommManager = deviceCommManager; } public ICommManager getCommManager() { return commManager; } public void setCommManager(ICommManager commManager) { this.commManager = commManager; idManager = commManager.getIdManager(); nodeId = idManager.getThisNetworkNode(); } public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } public void removeDeviceFromContainer(String deviceFamily, String deviceId) { if (deviceFamilyContainer.get(deviceFamily).get(deviceId) != null) { DeviceImpl deviceImpl = deviceFamilyContainer.get(deviceFamily) .get(deviceId); DeviceCommonInfo deviceCommon = new DeviceCommonInfo(deviceFamily, deviceImpl.getDeviceName(), deviceImpl.getDeviceType(), deviceImpl.getDeviceDescription(), deviceImpl.getDeviceConnectionType(), deviceImpl.getDeviceLocation(), deviceImpl.getDeviceProvider(), deviceImpl.getDeviceId(), deviceImpl.isContextSource()); deviceCommManager.fireDeviceDisconnected(deviceId, deviceCommon); deviceFamilyContainer.get(deviceFamily).remove(deviceId); deviceServiceNamesContainer.remove(deviceId); deviceIdBindingTable.inverseBidiMap().removeValue(deviceId); if (serviceRegistrationConatainer.get(deviceId) != null) { serviceRegistrationConatainer.get(deviceId).unregister(); } deviceImpl = null; deviceCommon = null; } } public List<String> getDeviceServiceNames(String deviceId) { LOG.info("////////////////////////////////// getDeviceServiceIds : " + deviceId); String[] deviceListArray = deviceServiceNamesContainer.get(deviceId); LOG.info(" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DeviceManager info: fireNewDeviceConnected " + deviceServiceNamesContainer.toString()); LOG.info("////////////////////////////////// getDeviceServiceIds : " + deviceListArray.toString()); if (deviceListArray != null) { LOG.info("////////////////////////////////// deviceListArray non null"); List<String> deviceNamesList = new ArrayList<String>(); for (String str : deviceListArray) { deviceNamesList.add(str); } LOG.info("////////////////////////////////// deviceListArray non null" + deviceNamesList.toString()); return deviceNamesList; } return null; } public String getPhysicalDeviceId(String deviceId) { String physicalDeviceId = (String) deviceIdBindingTable .inverseBidiMap().getKey(deviceId); LOG.info(" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DeviceManager info: getPhysicalDeviceId ::::::::::: " + physicalDeviceId); if (physicalDeviceId != null) { return physicalDeviceId; } return null; } // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ////Interfaces exposed to the device drivers // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * TODO Add in this method a call to a device binding table class to * generate an Id to each new device connected */ @Override public String fireNewDeviceConnected(String physicalDeviceId, DeviceCommonInfo deviceCommonInfo, String[] serviceNames) { LOG.info(" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DeviceManager info: fireNewDeviceConnected "); // Check if the device Family container contains device Instance // container for this family of devices if (deviceFamilyContainer.get(deviceCommonInfo.getDeviceFamilyIdentity()) == null) { // Create a new device instance container deviceInstanceContainer = new HashMap<String, DeviceImpl>(); // TODO here generate the deviceId from the CssId and CssNodeId // int deviceId = rdmNumber.nextInt(); String deviceId = nodeId.getJid() + "/" + deviceCommonInfo.getDeviceFamilyIdentity() + "/" + deviceCommonInfo.getDeviceType() + "/" + physicalDeviceId; deviceIdBindingTable.put(deviceId, physicalDeviceId); LOG.info(" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DeviceManager info: deviceIdBindingTable.getKey =" + deviceIdBindingTable.getKey(physicalDeviceId)); LOG.info(" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DeviceManager info: deviceIdBindingTable.inverseBidiMap().getKey =" + deviceIdBindingTable.inverseBidiMap().getKey(deviceId)); properties = new Hashtable<String, Object>(); properties.put(DeviceMgmtConstants.DEVICE_NODE_ID, nodeId.getJid()); properties.put(DeviceMgmtConstants.DEVICE_ID, deviceId); properties.put(DeviceMgmtConstants.DEVICE_NAME, deviceCommonInfo.getDeviceName()); properties.put(DeviceMgmtConstants.DEVICE_TYPE,deviceCommonInfo.getDeviceType()); properties.put(DeviceMgmtConstants.DEVICE_FAMILY,deviceCommonInfo.getDeviceFamilyIdentity()); properties.put(DeviceMgmtConstants.DEVICE_LOCATION,deviceCommonInfo.getDeviceLocation()); properties.put(DeviceMgmtConstants.DEVICE_PROVIDER,deviceCommonInfo.getDeviceProvider()); properties.put(DeviceMgmtConstants.DEVICE_CONNECTION_TYPE,deviceCommonInfo.getDeviceConnectionType()); if (deviceCommonInfo.getContextSource()) { properties.put(DeviceMgmtConstants.DEVICE_CONTEXT_SOURCE, "isContextSource"); } else { properties.put(DeviceMgmtConstants.DEVICE_CONTEXT_SOURCE, "isNotContextSource"); } // BJB : 31 08 2012 properties.put(TARGET_PLATFORM,"SOCIETIES"); properties.put(SERVICE_PROVIDER,"ICT-SOCIETIES"); Service deviceService = new Service(); deviceService.setServiceCategory(deviceCommonInfo.getDeviceType()); deviceService.setServiceDescription(deviceCommonInfo.getDeviceDescription()); deviceService.setServiceLocation(deviceCommonInfo.getDeviceLocation()); deviceService.setServiceName(deviceCommonInfo.getDeviceName()); deviceService.setServiceType(ServiceType.DEVICE); if (deviceCommonInfo.getContextSource()) { deviceService.setContextSource("isContextSource"); } else { deviceService.setContextSource("isNotContextSource"); } properties.put("ServiceMetaModel", deviceService); // END BJB 31 08 2012 // Object lock = new Object(); // create a new IDevice implementation deviceImpl = new DeviceImpl(this, nodeId.getJid(), deviceId, deviceCommonInfo); deviceInstanceContainer.put(deviceId, deviceImpl); deviceServiceNamesContainer.put(deviceId, serviceNames); LOG.info(" %%%%%%%%%%%%%%%%======================%%%%%%%%%%%%%%%%% DeviceManager info: fireNewDeviceConnected " + deviceServiceNamesContainer.toString()); deviceFamilyContainer.put( deviceCommonInfo.getDeviceFamilyIdentity(), deviceInstanceContainer); synchronized (this) { registration = bundleContext.registerService( IDevice.class.getName(), deviceImpl, properties); LOG.info("-- A device service with the deviceId: " + properties.get("deviceId") + " has been registred"); // Add the service registration to the map for future use (to // unregister a service, to change his property...etc) serviceRegistrationConatainer.put(deviceId, registration); // Adding generated deviceId to deviceCommonInfo object deviceCommonInfo.setDeviceID(deviceId); LOG.info("-- Device Manager before Broadcast"); // Broadcast the the device connected event to the other nodes deviceCommManager.fireNewDeviceConnected(deviceId, deviceCommonInfo); LOG.info("-- Device Manager after Broadcast"); return deviceId; } } else { // The bundle is Known, so get the device instance container deviceInstanceContainer = deviceFamilyContainer .get(deviceCommonInfo.getDeviceFamilyIdentity()); if (!deviceIdBindingTable.containsValue(physicalDeviceId)) { String deviceId = nodeId.getJid() + "/" + deviceCommonInfo.getDeviceFamilyIdentity() + "/" + deviceCommonInfo.getDeviceType() + "/" + physicalDeviceId; deviceIdBindingTable.put(deviceId, physicalDeviceId); properties = new Hashtable<String, Object>(); properties.put(DeviceMgmtConstants.DEVICE_NODE_ID, nodeId.getJid()); properties.put(DeviceMgmtConstants.DEVICE_ID, deviceId); properties.put(DeviceMgmtConstants.DEVICE_NAME, deviceCommonInfo.getDeviceName()); properties.put(DeviceMgmtConstants.DEVICE_TYPE, deviceCommonInfo.getDeviceType()); properties.put(DeviceMgmtConstants.DEVICE_FAMILY, deviceCommonInfo.getDeviceFamilyIdentity()); properties.put(DeviceMgmtConstants.DEVICE_LOCATION, deviceCommonInfo.getDeviceLocation()); properties.put(DeviceMgmtConstants.DEVICE_PROVIDER, deviceCommonInfo.getDeviceProvider()); properties.put(DeviceMgmtConstants.DEVICE_CONNECTION_TYPE, deviceCommonInfo.getDeviceConnectionType()); if (deviceCommonInfo.getContextSource()) { properties.put(DeviceMgmtConstants.DEVICE_CONTEXT_SOURCE, "isContextSource"); } else { properties.put(DeviceMgmtConstants.DEVICE_CONTEXT_SOURCE, "isNotContextSource"); } // BJB : 31 08 2012 properties.put(TARGET_PLATFORM,"SOCIETIES"); properties.put(SERVICE_PROVIDER,"ICT-SOCIETIES"); Service deviceService = new Service(); deviceService.setServiceCategory(deviceCommonInfo.getDeviceType()); deviceService.setServiceDescription(deviceCommonInfo.getDeviceDescription()); deviceService.setServiceLocation(deviceCommonInfo.getDeviceLocation()); deviceService.setServiceName(deviceCommonInfo.getDeviceName()); deviceService.setServiceType(ServiceType.DEVICE); if (deviceCommonInfo.getContextSource()) { deviceService.setContextSource("isContextSource"); } else { deviceService.setContextSource("isNotContextSource"); } properties.put("ServiceMetaModel", deviceService); // END BJB 31 08 2012 // Object lock = new Object(); // create a new IDevice implementation deviceImpl = new DeviceImpl(this, nodeId.getJid(), deviceId, deviceCommonInfo); deviceInstanceContainer.put(deviceId, deviceImpl); deviceServiceNamesContainer.put(deviceId, serviceNames); LOG.info(" %%%%%%%%%%%%%%%%======================%%%%%%%%%%%%%%%%% DeviceManager info: fireNewDeviceConnected " + deviceServiceNamesContainer.toString()); deviceFamilyContainer.put( deviceCommonInfo.getDeviceFamilyIdentity(), deviceInstanceContainer); synchronized (this) { registration = bundleContext.registerService( IDevice.class.getName(), deviceImpl, properties); LOG.info("-- A device service with the deviceId: " + properties.get("deviceId") + " has been registred"); // Add the service registration to the map for future use // (to unregister a service, to change his property...etc) serviceRegistrationConatainer.put(deviceId, registration); // Adding generated deviceId to deviceCommonInfo object deviceCommonInfo.setDeviceID(deviceId); LOG.info("-- Device Manager before Broadcast"); // Broadcast the the device connected event to the other // nodes deviceCommManager.fireNewDeviceConnected(deviceId, deviceCommonInfo); LOG.info("-- Device Manager after Broadcast"); return deviceId; } } return null; } } @Override public String fireDeviceDisconnected(String deviceFamily, String physicalDeviceId) { String deviceId = (String) deviceIdBindingTable .getKey(physicalDeviceId); if (deviceFamilyContainer.get(deviceFamily) != null) { if (deviceId != null) { if (deviceFamilyContainer.get(deviceFamily).get(deviceId) != null) { deviceFamilyContainer.get(deviceFamily).get(deviceId) .removeDevice(); return physicalDeviceId; } } else { return null; } } return null; } /** * Not implemented yet */ @Override public String fireNewDataReceived(String deviceFamily, String physicalDeviceId, Dictionary<String, Object> data) { return null; } @Override public String fireNewSharedDevice(DeviceCommonInfo deviceCommonInfo, IIdentity deviceNodeId) { LOG.info("-- Device Manager : create a new local device " + deviceCommonInfo.getDeviceName() + " representing a remote device connected to CSS Node " + deviceNodeId); return "device A"; } @Override public boolean fireDisconnectedSharedDevice(String deviceId) { // TODO Auto-generated method stub return true; } }