root/ossie/trunk/ossie/framework/DeviceManager_impl.cpp @ 3410

Revision 3410, 21.1 KB (checked in by balister, 6 years ago)

Through exception if dcd file not found. Clear up indentation.

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2004,2006, Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Core Framework.
6
7OSSIE Core Framework is free software; you can redistribute it and/or modify
8it under the terms of the Lesser GNU General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or
10(at your option) any later version.
11
12OSSIE Core Framework is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15Lesser GNU General Public License for more details.
16
17You should have received a copy of the Lesser GNU General Public License
18along with OSSIE Core Framework; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21Nov/10/03       C. Neely        Created
22C. Aguayo
23
24****************************************************************************/
25#include <iostream>
26
27#include <string.h>
28#ifdef HAVE_UNISTD_H
29#include <unistd.h>
30#else  /// \todo change else to ifdef windows var
31#include <process.h>
32#endif
33#ifdef HAVE_STDLIB_H
34#include <stdlib.h>
35#endif
36#include <errno.h>
37
38#include "ossie/debug.h"
39#include "ossie/ossieSupport.h"
40#include "ossie/DeviceManager_impl.h"
41#include "ossie/portability.h"
42
43DeviceManager_impl::~DeviceManager_impl ()
44{
45    DEBUG(6, DeviceManager, "Entering destructor.");
46}
47
48
49DeviceManager_impl::DeviceManager_impl(const char *DCDInput, const char *rootPath)
50
51{
52    DEBUG(6, DeviceManager, "Entering constructor with " << DCDInput);
53   
54    _deviceConfigurationProfile = DCDInput;
55    fsRoot = rootPath;
56}
57
58//Parsing constructor
59void DeviceManager_impl::post_constructor (CF::DeviceManager_var my_object_var)
60{
61    DEBUG(6, DeviceManager, "Entering post_constructor.");
62    orb_obj = new ossieSupport::ORB();
63
64    myObj = my_object_var;
65
66    _registeredDevices.length(0);
67    _registeredServices.length(0);
68
69    fs_servant = new FileSystem_impl(fsRoot.c_str());
70    _fileSys = fs_servant->_this();
71
72
73    if (_fileSys->exists (_deviceConfigurationProfile.c_str())) {
74        DEBUG(1, DeviceManager, "DCD File not found.");
75        throw (CF::FileException (CF::CFEEXIST, "DCD File not found."));
76    }
77   
78   
79    //Get Device Manager attributes (deviceConfigurationProfile, identifier and label)
80    //from DCD file
81   
82    CF::File_var file = _fileSys->open(_deviceConfigurationProfile.c_str(), true);
83   
84    DCDParser _DCDParser (file);
85   
86    _identifier = _DCDParser.getID();
87    _label = _DCDParser.getName();
88   
89    //get DomainManager reference
90   
91    getDomainManagerReference ((char *)_DCDParser.getDomainManagerName ());
92   
93    //Register DeviceManager with DomainManager
94    _dmnMgr->registerDeviceManager (my_object_var);
95   
96    _adminState = DEVMGR_REGISTERED;
97   
98    //parse filesystem names
99   
100    //Parse local componenents from DCD files
101    std::vector <componentPlacement> componentPlacements = _DCDParser.getComponentPlacements ();
102   
103    for (unsigned int i = 0; i < componentPlacements.size(); i++) {
104        CF::File_var file = _fileSys->open(_DCDParser.getFileNameFromRefId(componentPlacements[i].refId()), true);
105       
106        SPDParser _SPDParser (file);
107        file->close();
108       
109        //get code file name from implementation
110        std::vector < SPDImplementation * >*_implementations =
111            _SPDParser.getImplementations ();
112       
113        ///----------Assuming only one implementation
114        //spawn device
115       
116#ifdef MS_dotNET                        //FIXME PJB
117        int myPid2 = _spawnl (_P_DETACH,
118                              //Device Proxy
119                              (*_implementations)[0]->getCodeFile (),
120                              //argv[0]
121                              (*_implementations)[0]->getCodeFile (),
122                              componentPlacements[i].usageName(),     //Device Label --argv[1]
123                              _DCDParser.getFileNameFromRefId(componentPlacements[i].refId()),      //Device SoftwareProfile --argv[2]
124                              NULL);
125#endif
126#ifdef HAVE_WORKING_FORK
127        int myPid2;
128       
129        DEBUG(2, DevMgr, "Launching Device file " << (*_implementations)[0]->getCodeFile () << " Usage name " << componentPlacements[i].usageName());
130           
131        if ((myPid2 = fork()) < 0)
132            std::cout << "Fork Error" << std::endl;
133       
134        if (myPid2 == 0) {
135            // in child
136            if (getenv("VALGRIND")) {
137                std::string logFile = "--log-file=";
138                logFile += (*_implementations)[0]->getCodeFile ();
139                char *val = "/usr/local/bin/valgrind";
140                execl(val, val, logFile.c_str(), (*_implementations)[0]->getCodeFile (), componentPlacements[i].id(), componentPlacements[i].usageName() , _DCDParser.getFileNameFromRefId(componentPlacements[i].refId()), NULL);
141            } else {
142                execl((*_implementations)[0]->getCodeFile (), (*_implementations)[0]->getCodeFile (),componentPlacements[i].id(), componentPlacements[i].usageName() , _DCDParser.getFileNameFromRefId(componentPlacements[i].refId()), NULL);
143               
144            }
145            std::cout << "Device did not execute : " << strerror(errno) << std::endl;
146            exit (-1);
147        }
148#endif
149       
150        CORBA::Object_var _obj = CORBA::Object::_nil();
151        char nameStr[255];
152        sprintf( nameStr, "DomainName1/%s", componentPlacements[i].usageName() );
153        DEBUG(3, DevMgr, "searching for "<< nameStr);
154        do {
155            /// \todo sleep prevents system from beating Name Service to death, Fix better
156            ossieSupport::nsleep(0, 50*1000);
157            try {
158                _obj = orb_obj->get_object_from_name(nameStr);
159            } catch (CosNaming::NamingContext::NotFound) {};
160        }
161        while (CORBA::is_nil (_obj));
162        DEBUG(3, DevMgr, "found "<< nameStr);
163       
164        CF::Device_var tempDevice = CF::Device::_narrow (_obj);
165        tempDevice->initialize ();
166       
167        //Get properties from SCD
168        CF::File_var prfFile = _fileSys->open(_SPDParser.getPRFFile (), true);
169        PRFParser _PRFparser (prfFile);
170        prfFile->close();
171       
172        std::vector <PRFProperty *> *prfSimpleProp = _PRFparser.getConfigureProperties ();
173        CF::Properties configCapacities;
174        configCapacities.length (prfSimpleProp->size ());
175        for (unsigned int i = 0; i < prfSimpleProp->size (); i++) {
176            configCapacities[i] = *((*prfSimpleProp)[i]->getDataType ());
177        }
178       
179        //configure properties
180        DEBUG(3, DevMgr, "Configuring capacities");
181        tempDevice->configure (configCapacities);
182        DEBUG(3, DevMgr, "Registering device");
183        registerDevice (CF::Device::_duplicate(tempDevice));
184        DEBUG(3, DevMgr, "Device Registered");
185       
186    }
187   
188    //So far, it is assumed that all components are local
189    /*//Obtain DEPLY-ON components
190      std::vector<DCDComponentPlacement> DeployOnComponentsVector = _DCDParser.getDeployOnComponents();
191     
192      std::vector<char*> DPDList;
193     
194      //Get DPD file names from DeployOnComponentsVector
195      for(int i = 0; i < DeployOnComponentsVector.size(); i++) //Makes list of DPD files.
196      DPDList.push_back( DeployOnComponentsVector[i].getDPDFile() );
197    */
198   
199   
200}
201
202
203void
204DeviceManager_impl::init ()
205{
206    DEBUG(6, DeviceManager, "Entering init.");
207
208    _adminState = DEVMGR_UNREGISTERED;
209}
210
211
212void
213DeviceManager_impl::getDomainManagerReference (char *domainManagerName)
214{
215    DEBUG(6, DeviceManager, "Entering getDomainManagerReference.");
216
217    CORBA::Object_var obj = CORBA::Object::_nil();
218
219/// \todo sleep prevents system from beating Name Service to death, Fix better
220    do{
221      obj = orb_obj->get_object_from_name (domainManagerName);
222      usleep(1000);
223    }while(CORBA::is_nil(obj));
224
225    _dmnMgr = CF::DomainManager::_narrow (obj);
226}
227
228
229char *DeviceManager_impl::deviceConfigurationProfile ()
230throw (CORBA::SystemException)
231{
232    DEBUG(6, DeviceManager, "Entering deviceConfigurationProfile.");
233
234    std::string result;
235    ossieSupport::createProfileFromFileName(_deviceConfigurationProfile, result);
236    return CORBA::string_dup(result.c_str());
237}
238
239
240CF::FileSystem_ptr DeviceManager_impl::fileSys ()throw (CORBA::
241SystemException)
242{
243    DEBUG(6, DeviceManager, "Entering fileSys.");
244    CF::FileSystem_var result = _fileSys;
245    return result._retn();
246}
247
248
249char *DeviceManager_impl::identifier ()
250throw (CORBA::SystemException)
251{
252    DEBUG(6, DeviceManager, "Entering identifier.");
253    return CORBA::string_dup (_identifier.c_str());
254}
255
256
257char *DeviceManager_impl::label ()
258throw (CORBA::SystemException)
259{
260    DEBUG(6, DeviceManager, "Entering label.");
261    return CORBA::string_dup (_label.c_str());
262}
263
264
265CF::DeviceSequence *
266DeviceManager_impl::registeredDevices ()throw (CORBA::SystemException)
267{
268    DEBUG(6, DeviceManager, "Entering registeredDevices.");
269    CF::DeviceSequence_var result = new CF::DeviceSequence(_registeredDevices);
270    return result._retn();
271}
272
273
274CF::DeviceManager::ServiceSequence *
275DeviceManager_impl::registeredServices ()throw (CORBA::SystemException)
276{
277    DEBUG(6, DeviceManager, "Entering registeredServices.");
278    CF::DeviceManager::ServiceSequence_var result = new CF::DeviceManager::ServiceSequence(_registeredServices);
279    return result._retn();
280}
281
282
283void
284DeviceManager_impl::registerDevice (CF::Device_ptr registeringDevice)
285throw (CORBA::SystemException, CF::InvalidObjectReference)
286{
287    DEBUG(6, DeviceManager, "Entering registerDevice.");
288    if (CORBA::is_nil (registeringDevice)) {
289        //writeLogRecord(FAILURE_ALARM,invalid reference input parameter.)
290
291        throw (CF::
292            InvalidObjectReference
293            ("Cannot register Device. registeringDevice is a nil reference."));
294        return;
295    }
296
297    // Register the device with the Device manager, unless it is already
298    // registered
299    if (!deviceIsRegistered (registeringDevice)) {
300        _registeredDevices.length (_registeredDevices.length () + 1);
301        _registeredDevices[_registeredDevices.length () - 1] =
302            registeringDevice;
303    }
304
305    // If this Device Manager is registered with a Domain Manager, register
306    // the new device with the Domain Manager
307    if (_adminState == DEVMGR_REGISTERED) {
308        _dmnMgr->registerDevice (registeringDevice, myObj);
309    }
310
311//The registerDevice operation shall write a FAILURE_ALARM log record to a
312//DomainManagers Log, upon unsuccessful registration of a Device to the DeviceManagers
313//registeredDevices.
314}
315
316
317//This function returns TRUE if the input registeredDevice is contained in the _registeredDevices list attribute
318bool DeviceManager_impl::deviceIsRegistered (CF::Device_ptr registeredDevice)
319{
320    DEBUG(6, DeviceManager, "Entering deviceIsRegistered.");
321//Look for registeredDevice in _registeredDevices
322    for (unsigned int i = 0; i < _registeredDevices.length (); i++)
323    {
324        if (strcmp (_registeredDevices[i]->label (), registeredDevice->label ())
325            == 0)
326        {
327            return true;
328        }
329    }
330    return false;
331}
332
333
334//This function returns TRUE if the input serviceName is contained in the _registeredServices list attribute
335bool DeviceManager_impl::serviceIsRegistered (const char *serviceName)
336{
337    DEBUG(6, DeviceManager, "Entering serviceIsRegistered.");
338//Look for registeredDevice in _registeredDevices
339    for (unsigned int i = 0; i < _registeredServices.length (); i++)
340    {
341        if (strcmp (_registeredServices[i].serviceName, serviceName)  == 0)
342        {
343            return true;
344        }
345    }
346    return false;
347}
348
349
350void
351DeviceManager_impl::unregisterDevice (CF::Device_ptr registeredDevice)
352throw (CORBA::SystemException, CF::InvalidObjectReference)
353{
354    DEBUG(6, DeviceManager, "Entering unRegisterDevice.");
355    bool deviceFound = false;
356    if (CORBA::is_nil (registeredDevice))         //|| !deviceIsRegistered(registeredDevice) )
357    {
358//The unregisterDevice operation shall write a FAILURE_ALARM log record, when it cannot
359//successfully remove a registeredDevice from the DeviceManagers registeredDevices.
360
361//The unregisterDevice operation shall raise the CF InvalidObjectReference when the input
362//registeredDevice is a nil CORBA object reference or does not exist in the DeviceManagers
363//registeredDevices attribute.
364/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.); */
365        throw (CF::
366            InvalidObjectReference
367            ("Cannot unregister Device. registeringDevice is a nil reference."));
368
369        return;
370    }
371
372//The unregisterDevice operation shall remove the input registeredDevice from the
373//DeviceManagers registeredDevices attribute.
374
375//Look for registeredDevice in _registeredDevices
376    for (unsigned int i = 0; i < _registeredDevices.length (); i++)
377    {
378        if (strcmp (_registeredDevices[i]->label (), registeredDevice->label ())
379            == 0)
380        {
381//when the appropiater device is found, remove it from the _registeredDevices sequence
382            deviceFound = true;
383            if (_adminState == DEVMGR_REGISTERED)
384            {
385                _dmnMgr->unregisterDevice (CF::Device::_duplicate (registeredDevice));
386                CORBA::release (registeredDevice);
387            }
388            for (unsigned int j = i; j < _registeredDevices.length () - 1; j++)
389            {
390//The unregisterDevice operation shall unregister
391//the input registeredDevice from the DomainManager when the input registeredDevice is
392//registered with the DeviceManager and the DeviceManager is not shutting down.
393                _registeredDevices[j] = _registeredDevices[j + 1];
394            }
395//_registeredDevices[_registeredDevices.length() - 1] = 0;
396            _registeredDevices.length (_registeredDevices.length () - 1);
397//TO DO: Avoid memory leaks by reducing the length of the sequence _registeredDevices
398            break;
399        }
400    }
401    if (!deviceFound)
402    {
403/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.); */
404
405        throw (CF::
406            InvalidObjectReference
407            ("Cannot unregister Device. registeringDevice was not registered."));
408        return;
409    }
410
411}
412
413
414void
415DeviceManager_impl::shutdown ()
416throw (CORBA::SystemException)
417{
418    DEBUG(6, DeviceManager, "Entering shutdown.");
419    _adminState = DEVMGR_SHUTTING_DOWN;
420
421//The shutdown operation shall unregister the DeviceManager from the DomainManager.
422    _dmnMgr->unregisterDeviceManager (this->_this ()); ///\bug This looks wrong.
423
424//The shutdown operation shall perform releaseObject on all of the DeviceManagers registered
425//Devices (DeviceManagers registeredDevices attribute).
426
427    for (int i = _registeredDevices.length () - 1; i >= 0; i--)
428    {
429//Important Note: It is necessary to manage the lenght of the _registeredDevices sequence
430//otherwise, some elements in the sequence will be null.
431        _registeredDevices[i]->label ();          ////////////////////////////////////////////////test
432        CF::Device_var tempDev = CF::Device::_duplicate (_registeredDevices[i]);
433//_registeredDevices[i]->releaseObject();
434        unregisterDevice (_registeredDevices[i]);
435        tempDev->releaseObject ();
436    }
437
438}
439
440
441void
442DeviceManager_impl::registerService (CORBA::Object_ptr registeringService,
443const char *name)
444throw (CORBA::SystemException, CF::InvalidObjectReference)
445{
446    DEBUG(6, DeviceManager, "Entering registerService.");
447//This release does not support services
448    if (CORBA::is_nil (registeringService))
449    {
450/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.); */
451
452        throw (CF::
453            InvalidObjectReference
454            ("Cannot register Device. registeringDevice is a nil reference."));
455        return;
456    }
457
458//The registerService operation shall add the input registeringService to the DeviceManagers
459//registeredServices attribute when the input registeringService does not already exist in the
460//registeredServices attribute. The registeringService is ignored when duplicated.
461    if (!serviceIsRegistered (name))
462    {
463        _registeredServices.length (_registeredServices.length () + 1);
464        _registeredServices[_registeredServices.length () - 1].serviceObject = registeringService;
465        _registeredServices[_registeredServices.length () - 1].serviceName = name;
466    }
467
468//The registerService operation shall register the registeringService with the DomainManager
469//when the DeviceManager has already registered to the DomainManager and the
470//registeringService has been successfully added to the DeviceManagers registeredServices
471//attribute.
472    if (_adminState == DEVMGR_REGISTERED)
473    {
474        _dmnMgr->registerService (registeringService, this->_this (), name);
475    }
476
477//The registerService operation shall write a FAILURE_ALARM log record, upon unsuccessful
478//registration of a Service to the DeviceManagers registeredServices.
479//The registerService operation shall raise the CF InvalidObjectReference exception when the
480//input registeringService is a nil CORBA object reference.
481
482}
483
484
485void
486DeviceManager_impl::unregisterService (CORBA::Object_ptr registeredService,
487const char *name)
488throw (CORBA::SystemException, CF::InvalidObjectReference)
489{
490    DEBUG(6, DeviceManager, "Entering unRegisterService.");
491    if (CORBA::is_nil (registeredService))
492    {
493/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.); */
494
495        throw (CF::
496            InvalidObjectReference
497            ("Cannot unregister Service. registeringService is a nil reference."));
498        return;
499    }
500
501//The unregisterService operation shall remove the input registeredService from the
502//DeviceManagers registeredServices attribute. The unregisterService operation shall unregister
503//the input registeredService from the DomainManager when the input registeredService is
504//registered with the DeviceManager and the DeviceManager is not in the shutting down state.
505
506//Look for registeredService in _registeredServices
507    for (unsigned int i = 0; i < _registeredServices.length (); i++)
508    {
509        if (strcmp (_registeredServices[i].serviceName, name) == 0)
510        {
511//when the appropiater device is found, remove it from the _registeredDevices sequence
512            if (_adminState == DEVMGR_REGISTERED)
513            {
514                _dmnMgr->unregisterService (registeredService, name);
515            }
516
517            for (unsigned int j = i; j < _registeredServices.length ()-1; j++)
518            {
519
520                CORBA::release (registeredService);
521                _registeredServices[j] = _registeredServices[j+1];
522            }
523            _registeredServices.length (_registeredServices.length () - 1);
524            return;
525        }
526    }
527
528//If it didn't find registeredDevice, then throw an exception
529/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.);*/
530    throw (CF::
531        InvalidObjectReference
532        ("Cannot unregister Service. registeringService was not registered."));
533//The unregisterService operation shall write a FAILURE_ALARM log record, when it cannot
534//successfully remove a registeredService from the DeviceManagers registeredServices.
535//The unregisterService operation shall raise the CF InvalidObjectReference when the input
536//registeredService is a nil CORBA object reference or does not exist in the DeviceManagers
537//registeredServices attribute.
538}
539
540
541char *
542DeviceManager_impl::
543getComponentImplementationId (const char *componentInstantiationId)
544throw (CORBA::SystemException)
545{
546    DEBUG(6, DeviceManager, "Entering getComponentImplementationId.");
547//The getComponentImplementationId operation shall return the SPD implementation elements
548//ID attribute that matches the SPD implementation element used to create the component
549//identified by the input componentInstantiationId parameter.
550
551#if 0
552    DCDParser _DCDParser (_deviceConfigurationProfile);
553    std::vector < char *>*LocalComponentsVector =
554        _DCDParser.getLocalComponents ();
555#endif
556
557    std::cout << "If this appears look at DeviceManager_impl.cpp line 572" << std::endl;
558/*for (int i = 0; i<localComponentsVector->size();i++)
559   {
560   //get componentInstatiationId from each loal component
561   std::vector<ComponentInstantiation*> instantiations = LocalComponentsVector[i].getInstantiations();
562   //assuming only one instantiation
563   if( strcmp(componentInstantiationId, instantiations[0]->getID()) == 0)
564   {
565   SPDParser spdParser ( LocalComponentsVector[i].getSPDFile() );
566   std::vector<SPDImplementation*>  implementations = spdParser.getImplementations();
567   return implementations[0]->getID();
568   }
569} */
570    return "";
571
572//The getComponentImplementationId operation shall return an empty string when the input
573//componentInstantiationId parameter does not match the ID attribute of any SPD implementation
574//element used to create the component.
575}
576
577#ifdef AUTOMATIC_TEST
578
579void DeviceManager_impl::displayRegisteredDevices (void)
580{
581       
582    CF::Device_ptr myDev_ptr;
583    if(_registeredDevices.length() > 0)
584    {
585        std::cout << "Devices registered in "<<  this->label() <<" Device Manager"<< std::endl;
586        for (unsigned int i = 0; i < _registeredDevices.length(); i++)
587        {
588            myDev_ptr=CF::Device::_narrow(_registeredDevices[i]);
589            std::cout<< "\n  "<< myDev_ptr->label()<<std::endl;
590            //cout<<( "\n  %s\n",_registeredDevices[i]->label() );
591        }
592    }
593    else
594    {
595        std::cout<<"\nThere are no registered devices in "<<this->label()<<" Device Manager"<<std::endl;
596    }
597}
598
599void DeviceManager_impl::displayRegisteredServices (void)
600{
601    if( _registeredServices.length() > 0 )
602    {
603        std::cout<<"\nServices registered in "<<this->label() <<"Device Manager"<<std::endl;
604        for (unsigned int i = 0; i < _registeredServices.length(); i++)
605        {
606            if( CORBA::is_nil(_registeredServices[i].serviceObject) )
607                std::cout<<"\nInvalid object reference for "<<_registeredServices[i].serviceName<<std::endl;
608            else
609                std::cout<<"\n"<<_registeredServices[i].serviceName<<std::endl;
610        }
611    }
612    else
613    {
614        std::cout<<"\nThere are no registered services in "<<this->label()<<" Device Manager"<<std::endl;
615    }
616}
617#endif
Note: See TracBrowser for help on using the browser.