/***************************************************************************** * Copyright (c) 2008, University of Florida * All rights reserved. * * This file is part of OpenJAUS. OpenJAUS is distributed under the BSD * license. See the LICENSE file for details. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of the University of Florida nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * 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 * OWNER 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. ****************************************************************************/ // File Name: SystemTree.cpp // // Written By: Danny Kent (jaus AT dannykent DOT com) and Tom Galluzzo (galluzzo AT gmail DOT com) // // Version: 3.3.0a // // Date: 08/07/08 // // Description: This file defines the SystemTree class which manages the list of // JAUS subsystems and their associated nodes and components. #include #include "nodeManager/SystemTree.h" #include "utils/timeLib.h" #include "nodeManager/events/SystemTreeEvent.h" SystemTree::SystemTree(FileLoader *configData, EventHandler *handler) { this->configData = configData; this->registerEventHandler(handler); mySubsystemId = configData->GetConfigDataInt("JAUS", "SubsystemId"); myNodeId = configData->GetConfigDataInt("JAUS", "NodeId"); memset(system, 0, sizeof(system)); subsystemCount = 0; } SystemTree::~SystemTree(void) { for(int i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { if(system[i]) { jausSubsystemDestroy(system[i]); } } // TODO: Delete all the memory I own (system) } bool SystemTree::updateComponentTimestamp(JausAddress address) { JausComponent cmpt = findComponent(address); if(cmpt) { jausComponentUpdateTimestamp(cmpt); return true; } else { return false; } } bool SystemTree::updateNodeTimestamp(JausAddress address) { JausNode node = findNode(address); if(node) { jausNodeUpdateTimestamp(node); return true; } else { return false; } } bool SystemTree::updateSubsystemTimestamp(JausAddress address) { JausSubsystem subs = system[address->subsystem]; if(subs) { jausSubsystemUpdateTimestamp(subs); return true; } else { return false; } } unsigned char SystemTree::getNextInstanceId(JausAddress address) { bool instanceAvailable[JAUS_MAXIMUM_INSTANCE_ID] = {true}; int i = 0; for(i=0; i < JAUS_MAXIMUM_INSTANCE_ID; i++) { instanceAvailable[i] = true; } // Get this node JausNode node = findNode(address->subsystem, address->node); if(node) { // We'll go through all the attached components and check for matches for(i=0; i < node->components->elementCount; i++) { JausComponent cmpt = (JausComponent) node->components->elementData[i]; // if this is the same cmpt Id, we'll mark that instance as used if(cmpt->address->component == address->component) { instanceAvailable[cmpt->address->instance] = false; } } // Find the lowest value instance that is available i = JAUS_MINIMUM_INSTANCE_ID; while(i <= JAUS_MAXIMUM_INSTANCE_ID) { if(instanceAvailable[i]) { return i; } i++; } return JAUS_INVALID_INSTANCE_ID; } return JAUS_INVALID_INSTANCE_ID; } bool SystemTree::hasComponent(JausComponent cmpt) { JausAddress address = cmpt->address; return hasComponent(address->subsystem, address->node, address->component, address->instance); } bool SystemTree::hasComponent(JausAddress address) { return hasComponent(address->subsystem, address->node, address->component, address->instance); } bool SystemTree::hasComponent(int subsystemId, int nodeId, int componentId, int instanceId) { JausComponent cmpt = findComponent(subsystemId, nodeId, componentId, instanceId); if(cmpt) { return true; } else { return false; } } bool SystemTree::hasNode(JausNode node) { return hasNode(node->subsystem->id, node->id); } bool SystemTree::hasNode(JausAddress address) { return hasNode(address->subsystem, address->node); } bool SystemTree::hasNode(int subsystemId, int nodeId) { JausNode node = findNode(subsystemId, nodeId); if(node) { return true; } else { return false; } } bool SystemTree::hasSubsystem(JausSubsystem subsystem) { return hasSubsystem(subsystem->id); } bool SystemTree::hasSubsystem(JausAddress address) { return hasSubsystem(address->subsystem); } bool SystemTree::hasSubsystem(int subsystemId) { if(system[subsystemId]) { return true; } else { return false; } } bool SystemTree::hasSubsystemConfiguration(JausSubsystem subsystem) { return hasSubsystemConfiguration(subsystem->id); } // TODO: Move this to JausSubsystem bool SystemTree::hasSubsystemConfiguration(JausAddress address) { return hasSubsystemConfiguration(address->subsystem); } bool SystemTree::hasSubsystemConfiguration(int subsId) { if(system[subsId]) { JausSubsystem subs = system[subsId]; if(subs->nodes->elementCount > 0) { return true; } else { return false; } } else { return false; } } bool SystemTree::hasSubsystemIdentification(JausSubsystem subsystem) { return hasSubsystemIdentification(subsystem->id); } bool SystemTree::hasSubsystemIdentification(JausAddress address) { return hasSubsystemIdentification(address->subsystem); } bool SystemTree::hasSubsystemIdentification(int subsId) { JausSubsystem subs = system[subsId]; if(subs && subs->identification) { return true; } else { return false; } } bool SystemTree::hasNodeIdentification(JausNode node) { return hasNodeIdentification(node->subsystem->id, node->id); } bool SystemTree::hasNodeIdentification(JausAddress address) { return hasNodeIdentification(address->subsystem, address->node); } bool SystemTree::hasNodeIdentification(int subsystemId, int nodeId) { JausNode node = findNode(subsystemId, nodeId); if(node && node->identification) { return true; } else { return false; } } bool SystemTree::hasNodeConfiguration(JausAddress address) { JausNode node = findNode(address); if(node && node->components->elementCount > 0) { return true; } else { return false; } } bool SystemTree::hasComponentIdentification(JausAddress address) { return hasComponentIdentification(address->subsystem, address->node, address->component, address->instance); } bool SystemTree::hasComponentIdentification(int subsystemId, int nodeId, int componentId, int instanceId) { JausComponent cmpt = findComponent(subsystemId, nodeId, componentId, instanceId); if(cmpt && cmpt->identification) { return true; } else { return false; } } bool SystemTree::hasComponentServices(JausAddress address) { return hasComponentServices(address->subsystem, address->node, address->component, address->instance); } bool SystemTree::hasComponentServices(int subsystemId, int nodeId, int componentId, int instanceId) { JausComponent cmpt = findComponent(subsystemId, nodeId, componentId, instanceId); if(cmpt && cmpt->services->elementCount > 0) { return true; } else { return false; } } JausAddress SystemTree::lookUpAddress(JausAddress address) { return lookUpAddress(address->subsystem, address->node, address->component, address->instance); } JausAddress SystemTree::lookUpAddressInNode(JausNode node, int lookupCmpt, int lookupInst) { if(node) { for(int i = 0; i < node->components->elementCount; i++) { JausComponent cmpt = (JausComponent)node->components->elementData[i]; if(lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET) { if(lookupInst == JAUS_ADDRESS_WILDCARD_OCTET) { return jausAddressClone(cmpt->address); } else { if(cmpt->address->instance == lookupInst) { return jausAddressClone(cmpt->address); } } } else { if(cmpt->address->component == lookupCmpt) { if(lookupInst == JAUS_ADDRESS_WILDCARD_OCTET) { return jausAddressClone(cmpt->address); } else { if(cmpt->address->instance == lookupInst) { return jausAddressClone(cmpt->address); } } } } } } return NULL; } JausAddress SystemTree::lookUpAddressInSubsystem(JausSubsystem subs, int lookupNode, int lookupCmpt, int lookupInst) { if(subs) { if(lookupNode == JAUS_ADDRESS_WILDCARD_OCTET) { for(int i = 0; i < subs->nodes->elementCount; i++) { JausNode node = (JausNode)subs->nodes->elementData[i]; JausAddress address = lookUpAddressInNode(node, lookupCmpt, lookupInst); if(address) { return address; } } } else { return lookUpAddressInNode(findNode(subs->id, lookupNode), lookupCmpt, lookupInst); } } return NULL; } JausAddress SystemTree::lookUpAddress2(int lookupSubs, int lookupNode, int lookupCmpt, int lookupInst) { if(lookupSubs == JAUS_ADDRESS_WILDCARD_OCTET) { for(int i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { JausAddress address = lookUpAddressInSubsystem(system[i], lookupNode, lookupCmpt, lookupInst); if(address) { return address; } } } else { return lookUpAddressInSubsystem(system[lookupSubs], lookupNode, lookupCmpt, lookupInst); } return NULL; } JausAddress SystemTree::lookUpAddress(int lookupSubs, int lookupNode, int lookupCmpt, int lookupInst) { JausSubsystem subs = NULL; JausNode node = NULL; JausComponent cmpt = NULL; JausAddress address = jausAddressCreate(); if(!address) { // TODO: Log Error. Throw Exception. return NULL; } address->subsystem = JAUS_INVALID_SUBSYSTEM_ID; address->node = JAUS_INVALID_NODE_ID; address->component = JAUS_INVALID_COMPONENT_ID; address->instance = JAUS_INVALID_INSTANCE_ID; address->next = NULL; JausAddress returnAddress = address; // Find this address // If the subsystem is a wild card if(lookupSubs == JAUS_ADDRESS_WILDCARD_OCTET) { // Look through all subsystems for(int i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { subs = system[i]; if(!subs) { continue; } // If the node is a wild card if(lookupNode == JAUS_ADDRESS_WILDCARD_OCTET) { // Look through all nodes for(int j = 0; j < subs->nodes->elementCount; j++) { node = (JausNode) subs->nodes->elementData[j]; // If the component or the instance is a wild card if(lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET || lookupInst == JAUS_ADDRESS_WILDCARD_OCTET) { // Look through all components for(int k = 0; k < node->components->elementCount; k++) { cmpt = (JausComponent) node->components->elementData[k]; // If the component is wild card and this is the instance we are looking for if( lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->instance == lookupInst) { // If the address is valid (it should never be) if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); // Why do we clone if the address is valid?? if(!address->next) { return returnAddress; } else { address = address->next; } } // Address was not valid else { jausAddressCopy(address, cmpt->address); // Copy the address of the component we are looking at address->next = jausAddressCreate(); // Create a new address. Gets created even if we don't do anything else? if(!address->next) { return returnAddress; } else { address = address->next; } } } // If the instance is a wild card and this is the component we are looking for else if(lookupInst == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->component == lookupCmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } else { cmpt = findComponent(subs->id, node->id, lookupCmpt, lookupInst); if(cmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } } else { node = findNode(i, lookupNode); if(lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET || lookupInst == JAUS_ADDRESS_WILDCARD_OCTET) { // Look through all components for(int k = 0; k < node->components->elementCount; k++) { cmpt = (JausComponent) node->components->elementData[k]; if( lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->instance == lookupInst) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } else if(lookupInst == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->component == lookupCmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } else { cmpt = findComponent(subs->id, node->id, lookupCmpt, lookupInst); if(cmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } } } // We are looking within a specific subsystem else { subs = system[lookupSubs]; if(!subs) { // Subsystem not found // TODO: Log Error. Throw Exception. return address; } if(lookupNode == JAUS_ADDRESS_WILDCARD_OCTET) { // Look through all nodes for(int j = 0; j < subs->nodes->elementCount; j++) { node = (JausNode) subs->nodes->elementData[j]; if(lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET || lookupInst == JAUS_ADDRESS_WILDCARD_OCTET) { // Look through all components for(int k = 0; k < node->components->elementCount; k++) { cmpt = (JausComponent) node->components->elementData[k]; if( lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->instance == lookupInst) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } else if(lookupInst == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->component == lookupCmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } else { cmpt = findComponent(subs->id, node->id, lookupCmpt, lookupInst); if(cmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } } else { node = findNode(subs->id, lookupNode); if(lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET || lookupInst == JAUS_ADDRESS_WILDCARD_OCTET) { // Look through all components for(int k = 0; k < node->components->elementCount; k++) { cmpt = (JausComponent) node->components->elementData[k]; if( lookupCmpt == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->instance == lookupInst) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } else if(lookupInst == JAUS_ADDRESS_WILDCARD_OCTET && cmpt->address->component == lookupCmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } else { cmpt = findComponent(subs->id, node->id, lookupCmpt, lookupInst); if(cmpt) { if(jausAddressIsValid(address)) { address->next = jausAddressClone(cmpt->address); if(!address->next) { return returnAddress; } else { address = address->next; } } else { jausAddressCopy(address, cmpt->address); address->next = jausAddressCreate(); if(!address->next) { return returnAddress; } else { address = address->next; } } } } } } return returnAddress; } JausAddress SystemTree::lookUpServiceInSystem(int commandCode, int serviceType) { JausAddress list = NULL; JausAddress cur = list; if(serviceType != JAUS_SERVICE_INPUT_COMMAND && serviceType != JAUS_SERVICE_OUTPUT_COMMAND) { return NULL; } for(int i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { JausSubsystem subs = system[i]; if(!subs) { continue; } for(int j = 0; j < subs->nodes->elementCount; j++) { JausNode node = (JausNode) subs->nodes->elementData[j]; for(int k = 0; k < node->components->elementCount; k++) { JausComponent cmpt = (JausComponent) node->components->elementData[k]; for(int m = 0; m < cmpt->services->elementCount; m++) { JausService service = (JausService) cmpt->services->elementData[m]; JausCommand command = NULL; switch(serviceType) { case JAUS_SERVICE_INPUT_COMMAND: command = service->inputCommandList; break; case JAUS_SERVICE_OUTPUT_COMMAND: command = service->outputCommandList; break; default: // ERROR: Unknown service type // SHOULD NEVER GET HERE, CHECKED ABOVE return list; } while(command) { if(command->commandCode == commandCode) { // YAY... we found a matching commandCode // Add this component's address to our list JausAddress address = jausAddressClone(cmpt->address); address->next = NULL; if(list == NULL) { list = address; cur = list->next; } else { cur->next = address; cur = cur->next; } // This is a cheat to skip the rest of the commands // since a command should not repeat command = NULL; } else { command = command->next; } } } } } } return list; } JausSubsystem *SystemTree::getSystem(void) { if(subsystemCount == 0) { return NULL; } JausSubsystem *systemClone = (JausSubsystem *)malloc(subsystemCount*sizeof(JausSubsystem)); int systemCloneIndex = 0; for(int i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { if(system[i]) { systemClone[systemCloneIndex] = jausSubsystemClone(system[i]); systemCloneIndex++; } } return systemClone; } JausSubsystem SystemTree::getSubsystem(JausSubsystem subsystem) { return getSubsystem(subsystem->id); } JausSubsystem SystemTree::getSubsystem(JausAddress address) { return getSubsystem(address->subsystem); } JausSubsystem SystemTree::getSubsystem(int subsystemId) { JausSubsystem subs = system[subsystemId]; if(subs) { return jausSubsystemClone(subs); } return NULL; } JausNode SystemTree::getNode(JausNode node) { return getNode(node->subsystem->id, node->id); } JausNode SystemTree::getNode(JausAddress address) { return getNode(address->subsystem, address->node); } JausNode SystemTree::getNode(int subsystemId, int nodeId) { JausNode node = findNode(subsystemId, nodeId); if(node) { return jausNodeClone(node); } return NULL; } JausComponent SystemTree::getComponent(JausComponent cmpt) { return getComponent(cmpt->address->subsystem, cmpt->address->node, cmpt->address->component, cmpt->address->instance); } JausComponent SystemTree::getComponent(JausAddress address) { return getComponent(address->subsystem, address->node, address->component, address->instance); } JausComponent SystemTree::getComponent(int subsystemId, int nodeId, int componentId, int instanceId) { JausComponent cmpt = findComponent(subsystemId, nodeId, componentId, instanceId); if(cmpt) { return jausComponentClone(cmpt); } return NULL; } JausNode SystemTree::findNode(JausNode node) { return findNode(node->subsystem->id, node->id); } JausNode SystemTree::findNode(JausAddress address) { return findNode(address->subsystem, address->node); } JausNode SystemTree::findNode(int subsId, int nodeId) { JausSubsystem subs = system[subsId]; if(subs) { for(int i = 0; i < subs->nodes->elementCount; i++) { JausNode node = (JausNode)subs->nodes->elementData[i]; if(node->id == nodeId) { return node; } } } return NULL; } JausComponent SystemTree::findComponent(JausComponent cmpt) { return findComponent(cmpt->address->subsystem, cmpt->address->node, cmpt->address->component, cmpt->address->instance); } JausComponent SystemTree::findComponent(JausAddress address) { return findComponent(address->subsystem, address->node, address->component, address->instance); } JausComponent SystemTree::findComponent(int subsId, int nodeId, int cmptId, int instId) { JausSubsystem subs = system[subsId]; if(subs) { for(int i = 0; i < subs->nodes->elementCount; i++) { JausNode node = (JausNode)subs->nodes->elementData[i]; if(node->id == nodeId) { for(int i = 0; i < node->components->elementCount; i++) { JausComponent cmpt = (JausComponent)node->components->elementData[i]; if( cmpt->address->component == cmptId && cmpt->address->instance == instId ) { return cmpt; } } return NULL; } } } return NULL; } bool SystemTree::addComponent(JausComponent cmpt) { return addComponent(cmpt->address->subsystem, cmpt->address->node, cmpt->address->component, cmpt->address->instance, cmpt); } bool SystemTree::addComponent(JausAddress address, JausComponent cmpt) { return addComponent(address->subsystem, address->node, address->component, address->instance, cmpt); } bool SystemTree::addComponent(int subsystemId, int nodeId, int componentId, int instanceId, JausComponent cmpt) { if(!this->hasComponent(subsystemId, nodeId, componentId, instanceId)) { JausNode node = findNode(subsystemId, nodeId); if(node && componentId >= JAUS_MINIMUM_COMPONENT_ID && componentId <= JAUS_MAXIMUM_COMPONENT_ID && instanceId >= JAUS_MINIMUM_INSTANCE_ID && instanceId <= JAUS_MAXIMUM_INSTANCE_ID) { // Add the component to the node if(cmpt) { cmpt = jausComponentClone(cmpt); } else { cmpt = jausComponentCreate(); cmpt->address->instance = instanceId; cmpt->address->component = componentId; cmpt->address->node = nodeId; cmpt->address->subsystem = subsystemId; } cmpt->node = node; jausArrayAdd(node->components, cmpt); SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::ComponentAdded, cmpt); this->handleEvent(e); return true; } } return false; } bool SystemTree::addNode(JausNode node) { return addNode(node->subsystem->id, node->id, node); } bool SystemTree::addNode(JausAddress address, JausNode node) { return addNode(address->subsystem, address->node, node); } bool SystemTree::addNode(int subsystemId, int nodeId, JausNode node) { if(!this->hasNode(subsystemId, nodeId)) { JausSubsystem subs = system[subsystemId]; if(subs && nodeId >= JAUS_MINIMUM_NODE_ID && nodeId <= JAUS_MAXIMUM_NODE_ID) { if(node) { node = jausNodeClone(node); } else { node = jausNodeCreate(); node->id = nodeId; } node->subsystem = subs; jausArrayAdd(subs->nodes, node); SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::NodeAdded, node); this->handleEvent(e); return true; } } return false; } bool SystemTree::addSubsystem(JausSubsystem subs) { return addSubsystem(subs->id, subs); } bool SystemTree::addSubsystem(JausAddress address, JausSubsystem subs) { return addSubsystem(address->subsystem, subs); } bool SystemTree::addSubsystem(int subsystemId, JausSubsystem subs) { if(!this->hasSubsystem(subsystemId)) { // Test for valid ID if(subsystemId >= JAUS_MINIMUM_SUBSYSTEM_ID && subsystemId <= JAUS_MAXIMUM_SUBSYSTEM_ID) { if(subs) { subs = jausSubsystemClone(subs); } else { subs = jausSubsystemCreate(); subs->id = subsystemId; } system[subs->id] = subs; subsystemCount++; SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::SubsystemAdded, subs); this->handleEvent(e); return true; } } return false; } bool SystemTree::removeNode(JausNode node) { return removeNode(node->subsystem->id, node->id); } bool SystemTree::removeNode(JausAddress address) { return removeNode(address->subsystem, address->node); } bool SystemTree::removeNode(int subsystemId, int nodeId) { JausSubsystem subs = system[subsystemId]; if(subs) { for(int i=0; inodes->elementCount; i++) { JausNode node = (JausNode)subs->nodes->elementData[i]; if(nodeId == node->id) { jausArrayRemoveAt(subs->nodes, i); SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::NodeRemoved, node); this->handleEvent(e); jausNodeDestroy(node); return true; } } } return false; } bool SystemTree::removeSubsystem(JausSubsystem subs) { return removeSubsystem(subs->id); } bool SystemTree::removeSubsystem(JausAddress address) { return removeSubsystem(address->subsystem); } bool SystemTree::removeSubsystem(int subsystemId) { JausSubsystem subs = system[subsystemId]; if(subs) { system[subsystemId] = NULL; SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::SubsystemRemoved, subs); this->handleEvent(e); jausSubsystemDestroy(subs); subsystemCount--; return true; } return false; } bool SystemTree::removeComponent(JausComponent cmpt) { return removeComponent(cmpt->address->subsystem, cmpt->address->node, cmpt->address->component, cmpt->address->instance); } bool SystemTree::removeComponent(JausAddress address) { return removeComponent(address->subsystem, address->node, address->component, address->instance); } bool SystemTree::removeComponent(int subsystemId, int nodeId, int componentId, int instanceId) { JausNode node = findNode(subsystemId, nodeId); if(node) { for(int i = 0; i < node->components->elementCount; i++) { JausComponent cmpt = (JausComponent) node->components->elementData[i]; if(cmpt->address->component == componentId && cmpt->address->instance == instanceId) { jausArrayRemoveAt(node->components, i); SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::ComponentRemoved, cmpt); this->handleEvent(e); jausComponentDestroy(cmpt); return true; } } } return false; } bool SystemTree::replaceSubsystem(JausAddress address, JausSubsystem newSubs) { return replaceSubsystem(address->subsystem, newSubs); } bool SystemTree::replaceSubsystem(int subsystemId, JausSubsystem newSubs) { JausSubsystem currentSubs = system[subsystemId]; if(!currentSubs) { addSubsystem(subsystemId, newSubs); // No subsystem to replace, so add the newSubs return true; } JausSubsystem cloneSubs = jausSubsystemClone(newSubs); if(!cloneSubs) { return false; } if(currentSubs->identification) { size_t stringLength = strlen(currentSubs->identification) + 1; cloneSubs->identification = (char *) realloc(cloneSubs->identification, stringLength); sprintf(cloneSubs->identification, "%s", currentSubs->identification); } for(int i = 0; i < cloneSubs->nodes->elementCount; i++) { JausNode cloneNode = (JausNode)cloneSubs->nodes->elementData[i]; JausNode currentNode = findNode(cloneNode); if(currentNode) { if(currentNode->identification) { size_t stringLength = strlen(currentNode->identification) + 1; cloneNode->identification = (char *) realloc(cloneNode->identification, stringLength); sprintf(cloneNode->identification, "%s", currentNode->identification); } for(int i = 0; i < cloneNode->components->elementCount; i++) { JausComponent cloneCmpt = (JausComponent)cloneNode->components->elementData[i]; JausComponent currentCmpt = findComponent(cloneCmpt); if(currentCmpt && currentCmpt->identification) { size_t stringLength = strlen(currentCmpt->identification) + 1; cloneCmpt->identification = (char *) realloc(cloneCmpt->identification, stringLength); sprintf(cloneCmpt->identification, "%s", currentNode->identification); } } } } jausSubsystemDestroy(system[subsystemId]); system[subsystemId] = cloneSubs; subsystemCount++; //char string[1024] = {0}; //jausSubsystemTableToString(cloneSubs, string); //printf("Replaced Subsystem: \n%s\n", string); return true; } bool SystemTree::replaceNode(JausAddress address, JausNode newNode) { return replaceNode(address->subsystem, address->node, newNode); } bool SystemTree::replaceNode(int subsystemId, int nodeId, JausNode newNode) { JausNode currentNode = findNode(subsystemId, nodeId); if(!currentNode) { // No node to replace, so add the newNode addNode(subsystemId, nodeId, newNode); return true; } JausNode cloneNode = jausNodeCreate(); if(!cloneNode) { return false; } cloneNode->id = currentNode->id; size_t stringLength = strlen(currentNode->identification) + 1; cloneNode->identification = (char *) realloc(cloneNode->identification, stringLength); sprintf(cloneNode->identification, "%s", currentNode->identification); cloneNode->subsystem = currentNode->subsystem; for(int i = 0; i < newNode->components->elementCount; i++) { JausComponent newCmpt = (JausComponent)newNode->components->elementData[i]; JausComponent addCmpt = findComponent(newCmpt); if(addCmpt) { addCmpt = jausComponentClone(addCmpt); } else { addCmpt = jausComponentCreate(); addCmpt->address->subsystem = subsystemId; addCmpt->address->node = nodeId; addCmpt->address->component = newCmpt->address->component; addCmpt->address->instance = newCmpt->address->instance; } addCmpt->node = cloneNode; jausArrayAdd(cloneNode->components, addCmpt); } for(int i = 0; i < system[subsystemId]->nodes->elementCount; i++) { JausNode node = (JausNode)system[subsystemId]->nodes->elementData[i]; if(currentNode->id == node->id) { jausArrayRemoveAt(system[subsystemId]->nodes, i); jausNodeDestroy(node); break; } } cloneNode->subsystem = system[subsystemId]; jausArrayAdd(system[subsystemId]->nodes, cloneNode); return true; } bool SystemTree::setSubsystemIdentification(JausAddress address, char *identification) { JausSubsystem subs = system[address->subsystem]; if(subs) { size_t stringLength = strlen(identification) + 1; subs->identification = (char *) realloc(subs->identification, stringLength); if(subs->identification) { sprintf(subs->identification, "%s", identification); return true; } } return false; } bool SystemTree::setNodeIdentification(JausAddress address, char *identification) { JausNode node = findNode(address); if(node) { size_t stringLength = strlen(identification) + 1; node->identification = (char *) realloc(node->identification, stringLength); if(node->identification) { sprintf(node->identification, "%s", identification); return true; } } return false; } bool SystemTree::setComponentIdentification(JausAddress address, char *identification) { JausComponent cmpt = findComponent(address); if(cmpt) { size_t stringLength = strlen(identification) + 1; cmpt->identification = (char *) realloc(cmpt->identification, stringLength); if(cmpt->identification) { sprintf(cmpt->identification, "%s", identification); return true; } } return false; } bool SystemTree::setComponentServices(JausAddress address, JausArray inputServices) { JausComponent cmpt = findComponent(address); if(cmpt) { // Remove current service set if(cmpt->services) jausServicesDestroy(cmpt->services); cmpt->services = jausServicesClone(inputServices); return true; } return false; } char *SystemTree::getSubsystemIdentification(JausSubsystem subsystem) { return getSubsystemIdentification(subsystem->id); } char *SystemTree::getSubsystemIdentification(JausAddress address) { return getSubsystemIdentification(address->subsystem); } char *SystemTree::getSubsystemIdentification(int subsId) { char *string = NULL; JausSubsystem subs = system[subsId]; if(subs) { string = (char *)calloc(strlen(subs->identification)+1, sizeof(char)); strcpy(string, subs->identification); return string; } else { return NULL; } } char *SystemTree::getNodeIdentification(JausNode node) { return getNodeIdentification(node->subsystem->id, node->id); } char *SystemTree::getNodeIdentification(JausAddress address) { return getNodeIdentification(address->subsystem, address->node); } char *SystemTree::getNodeIdentification(int subsId, int nodeId) { char *string = NULL; JausNode node = findNode(subsId, nodeId); if(node) { string = (char *)calloc(strlen(node->identification)+1, sizeof(char)); strcpy(string, node->identification); return string; } else { return NULL; } } std::string SystemTree::toString() { string output = string(); char buffer[4096] = {0}; if(subsystemCount == 0) { return "System Tree Empty\n"; } for(int i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { if(system[i]) { jausSubsystemTableToString(system[i], buffer); output += buffer; output += "\n"; } } return output; } std::string SystemTree::toDetailedString() { string output = string(); char buffer[20480] = {0}; if(subsystemCount == 0) { return "System Tree Empty\n"; } for(int i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { if(system[i]) { jausSubsystemTableToDetailedString(system[i], buffer); output += buffer; output += "\n"; } } return output; } void SystemTree::refresh() { int i = 0; int j = 0; int k = 0; for(i = JAUS_MINIMUM_SUBSYSTEM_ID; i < JAUS_MAXIMUM_SUBSYSTEM_ID; i++) { if(system[i]) { if(system[i]->id == mySubsystemId) { for(j = 0; j < system[i]->nodes->elementCount; j++) { JausNode node = (JausNode) system[i]->nodes->elementData[j]; if(node->id == myNodeId) { for(k = 0; k < node->components->elementCount; k++) { JausComponent cmpt = (JausComponent) node->components->elementData[k]; if(jausComponentIsTimedOut(cmpt)) { //NOTE: The order here is important b/c event handlers may inspect the system tree and // we have to remove the cmpt from the tree before we notify of the change // Create Subsystem Event SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::ComponentTimeout, cmpt); // Remove this component jausArrayRemoveAt(node->components, k); k--; // Destroy this memory jausComponentDestroy(cmpt); // Send off our event this->handleEvent(e); } } } else { if(jausNodeIsTimedOut(node)) { //NOTE: The order here is important b/c event handlers may inspect the system tree and // we have to remove the node from the tree before we notify of the change // Create a timeout event SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::NodeTimeout, node); // Remove the Node removeNode(node); // Handle the event this->handleEvent(e); } } } } else { if(jausSubsystemIsTimedOut(system[i])) { //NOTE: The order here is important b/c event handlers may inspect the system tree and // we have to remove the node from the tree before we notify of the change // Create our event with the proper information SystemTreeEvent *e = new SystemTreeEvent(SystemTreeEvent::SubsystemTimeout, system[i]); // Remove the dead subsystem removeSubsystem(system[i]->id); // Handle the event this->handleEvent(e); } } } } } bool SystemTree::registerEventHandler(EventHandler *handler) { if(handler) { this->eventHandlers.push_back(handler); return true; } return false; } void SystemTree::handleEvent(NodeManagerEvent *e) { // Send to all registered handlers std::list ::iterator iter; for(iter = eventHandlers.begin(); iter != eventHandlers.end(); iter++) { (*iter)->handleEvent(e->cloneEvent()); } delete e; }