// $Id: JGEquipment.cpp,v 1.12 2003/03/23 04:57:08 fukasawa Exp $

//=============================================================================
/**
 *  @file    JGEquipment.cpp
 *
 *  @author Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2001-2003 BEE Co.,Ltd. All rights reserved.
 *
 * This program 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 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
//=============================================================================

#define BEE_BUILD_DLL

#include "JGEquipment.h"
#include "JGInfoManager.h"
#include "JGAlarmManager.h"
#include "JGCommManager.h"
#include "JGControlManager.h"
#include "JGEventManager.h"
#include "JGLimitManager.h"
#include "JGProcessManager.h"
#include "JGSpoolManager.h"
#include "JGTerminalManager.h"
#include "JGTraceManager.h"
#include "JGAccessManager.h"
#include "JGTimeModule.h"
#include "JGEventManager.h"
#include "JGObjectManager.h"
#include "PLCDeviceManager.h"
#include "sac/JGIODevManager.h"
#include "dbio/DBAlarmElm.h"
#include "dbio/DBConfigElm.h"
#include "dbio/DBEventElm.h"
#include "dbio/DBIODeviceElm.h"
#include "dbio/DBLimitElm.h"
#include "dbio/DBReportElm.h"
#include "dbio/DBSpoolElm.h"
#include "dbio/DBTraceElm.h"
#include "dbio/DBTriggerInfoElm.h"
#include "dbio/DBVariableElm.h"
#include "dbio/DBSubSystemElm.h"
#include "JGTaskTrigger.h"
#include "JGCommDevice.h"
#include "arams/Arams.h"
#include "JGResourceManager.h"
#include "JGRecipeManager.h"
#include "JGProcProgManager.h"

#ifdef GEM300
#include "JGMateIOManager.h"
#include "JGMaterialManager.h"
#else
#include "JGMateMoveManager.h"
#endif
#include "JGLogFileManager.h"

#include "JGLogTime.h"
static JGLogTime _logtime;

typedef PLCDeviceManager * (*PLCManagerCreator)(void);

//-----------------------------------------------------------------------------
//
// Watching timeout module
//
//-----------------------------------------------------------------------------
class TimeWatcher : public ACE_Task <ACE_NULL_SYNCH>
{
public:
    int svc (void)
    {
        // ACE_DEBUG((LM_DEBUG,
        //     ACE_TEXT("(%t): Starting run_event_loop() in TimeWatcher\n")));
        if (ACE_Proactor::run_event_loop() == -1)
        {
            ACE_ERROR_RETURN((LM_ERROR,
                    ACE_TEXT("(%t):%p.\n"), ACE_TEXT("Worker::svc")), -1);
        }
        ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) work complete\n")));
        return 0;
    }
};

//-----------------------------------------------------------------------------
//
// Equipment Manager
//
//-----------------------------------------------------------------------------
ACE_Object_Manager * ace_object_manager;

static JGEquipment * _manager = NULL;
static BCHAR * _versionNum = _TX("0.2.5");
static TimeWatcher * _timer = NULL;

//-----------------------------------------------------------------------------
// Constructor/Destructor
//-----------------------------------------------------------------------------
JGEquipment::JGEquipment() : JGManager(_TX("EQUIPMENT"))
{
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGEquipment::JGEquipment");

    ACE::init();

    ace_object_manager = ACE_Object_Manager::instance();

    m_plc_mngr = NULL;
    m_info_mngr = NULL;
    m_arams = NULL;
    m_alarm_mngr = NULL;
    m_comm_mngr = NULL;
    m_control_mngr = NULL;
    m_event_mngr = NULL;
    m_spool_mngr = NULL;
    m_limit_mngr = NULL;
    m_process_mngr = NULL;
    m_terminal_mngr = NULL;
    m_trace_mngr = NULL;
    m_rcmd_mngr = NULL;
    m_iodev_mngr = NULL;
    m_obj_mngr = NULL;
    m_resource_mngr = NULL;
    m_recipe_mngr = NULL;
#ifdef GEM300
    m_material_mngr = NULL;
    m_mateio_mngr = NULL;
#else
    m_matemove_mngr = NULL;
#endif
    m_systime = NULL;
    m_pcReady = NULL;

    m_rootPath = DIR_SEPARATOR_STRING;
    m_rootPath += _TX("jyugem");

}
//-----------------------------------------------------------------------------
JGEquipment::~JGEquipment()
{
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGEquipment::~JGEquipment");
}

//-----------------------------------------------------------------------------
// Return own.
//-----------------------------------------------------------------------------
JGEquipment * JGEquipment::instance()
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::instance");
    if (_manager == NULL)
    {
        _manager = new JGEquipment;
    }
    return _manager;
}

//-----------------------------------------------------------------------------
JGEquipment * JGEquipment::instance(JGEquipment * app)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::instance");
    if (_manager == NULL)
    {
        if (app != NULL)
        {
            _manager = new JGEquipment;
        }
        else
        {
            _manager = app;
        }
    }
    return _manager;
}

//-----------------------------------------------------------------------------
// Initialize
//-----------------------------------------------------------------------------
int JGEquipment::init(void * parm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::init");
    ACE_UNUSED_ARG(parm);

    this->init_log();

    //
    // Load DLL of PLC Manager
    //
    int retval = m_dll.open(m_plcName.c_str());
    if (retval != 0)
    {
        ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%p : %s"), ACE_TEXT("dll.open"),
                                                         m_plcName.c_str()), -1);
    }
    PLCManagerCreator pmc;
    pmc = (PLCManagerCreator)m_dll.symbol("CreatePLC");
    if (pmc == 0)
    {
        ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%p: %s"), ACE_TEXT("dll.symbol"),
                                                        m_plcName.c_str()), -1);
    }
    m_plc_mngr = pmc();

    //
    // Create gem managers
    //
    m_obj_mngr = ObjManager::instance();
    m_obj_mngr->equipment(this);
    m_managers.push_back(m_obj_mngr);

    m_info_mngr = JGInfoManager::instance();
    m_info_mngr->equipment(this);
    m_managers.push_back(m_info_mngr);

    m_systime = JGTimeModule::instance();
    m_systime->equipment(this);
    m_managers.push_back(m_systime);

    m_alarm_mngr = JGAlarmManager::instance();
    m_alarm_mngr->equipment(this);
    m_managers.push_back(m_alarm_mngr);

    m_comm_mngr = JGCommManager::instance();
    m_comm_mngr->equipment(this);
    m_managers.push_back(m_comm_mngr);

    m_control_mngr = JGControlManager::instance();
    m_control_mngr->equipment(this);
    m_managers.push_back(m_control_mngr);

    m_event_mngr = JGEventManager::instance();
    m_event_mngr->equipment(this);
    m_managers.push_back(m_event_mngr);

    m_spool_mngr = JGSpoolManager::instance();
    m_spool_mngr->equipment(this);
    m_managers.push_back(m_spool_mngr);

    m_terminal_mngr = JGTerminalManager::instance();
    m_terminal_mngr->equipment(this);
    m_managers.push_back(m_terminal_mngr);

    m_limit_mngr = JGLimitManager::instance();
    m_limit_mngr->equipment(this);
    m_managers.push_back(m_limit_mngr);

    m_process_mngr = JGProcessManager::instance();
    m_process_mngr->equipment(this);
    m_managers.push_back(m_process_mngr);

    m_trace_mngr = JGTraceManager::instance();
    m_trace_mngr->equipment(this);
    m_managers.push_back(m_trace_mngr);

    m_rcmd_mngr = JGAccessManager::instance();
    m_rcmd_mngr->equipment(this);
    m_managers.push_back(m_rcmd_mngr);

    m_iodev_mngr = JGIODevManager::instance();
    m_iodev_mngr->equipment(this);
    m_managers.push_back(m_iodev_mngr);

    m_resource_mngr = JGResourceManager::instance();
    m_resource_mngr->equipment(this);
    m_managers.push_back(m_resource_mngr);

#ifdef GEM300
    m_material_mngr = JGMaterialManager::instance();
    m_material_mngr->equipment(this);
    m_managers.push_back(m_material_mngr);

    m_mateio_mngr = JGMateIOManager::instance();
    m_mateio_mngr->equipment(this);
    m_managers.push_back(m_mateio_mngr);
#else
    m_matemove_mngr = JGMateMoveManager::instance();
    m_matemove_mngr->equipment(this);
    m_managers.push_back(m_matemove_mngr);
#endif

    m_recipe_mngr = JGRecipeManager::instance();
    m_recipe_mngr->equipment(this);
    m_managers.push_back(m_recipe_mngr);

    m_pp_mngr = JGProcProgManager::instance();
    m_pp_mngr->equipment(this);
    m_managers.push_back(m_pp_mngr);

    m_arams = Arams::instance();
    m_arams->equipment(this);
    m_managers.push_back(m_arams);

    // Load data from DB
    retval = this->load();
    if (retval < 0)
    {
        return retval;
    }

    // create device
    JGCommDevice * devptr = this->initDevice();
    if (devptr < 0)
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT("JGEquipment Loaded Error SECS Driver.\n")));
        return BEE_ERROR;
    }
    this->act_managers(devptr);

    // start timer for watchdog
    _timer = new TimeWatcher;
    if (_timer->activate(THR_NEW_LWP) == -1)
    {
        ACE_ERROR_RETURN((LM_ERROR,
                ACE_TEXT("%p.\n"), ACE_TEXT("equipment")), BEE_ERROR);
    }

    ACE_OS::sleep(1);
    m_alarm_mngr->initAlarmsSet();   // Get alarm bits

    return BEE_SUCCESS;
}

//-----------------------------------------------------------------------------
// Initialize equipment/host device
//-----------------------------------------------------------------------------
JGCommDevice * JGEquipment::initDevice()
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::initDevice");

    JGCommDevice * device = new JGCommDevice;
    // read config table
    DeviceParameter * dparm = m_info_mngr->getDeviceParameter();

    const string& equipName = this->getConf(CONF_EQUIP_NAME);
    BS2Assert(equipName.size() > 0);    // check parameter value
    device->setName(equipName.c_str());
    if (device->initialize(dparm) >= 0)
    {
        device->setEquipment(this);
    }
    else
    {
        TRACE_ERROR((_TX("%s manager does not initialize device.\n"),
                     this->charName()));
        delete device;
        device = NULL;
    }
    delete dparm;
    m_device = device;
    return device;
}

//-----------------------------------------------------------------------------
// Stop peocess
//-----------------------------------------------------------------------------
int JGEquipment::stop(u_long parm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::stop");
    ACE_UNUSED_ARG(parm);

    ACE_DEBUG((LM_DEBUG,
              ACE_TEXT("Stopping Managers ......\n")));

    this->stop_managers();              // Stop services

    ACE_Reactor::instance()->end_reactor_event_loop();
    ACE_Proactor::end_event_loop();

    ACE_OS::sleep(2);

    ACE_DEBUG((LM_DEBUG,
              ACE_TEXT("Saving equipment data ......\n")));

    // Save data to DB
    // this->save();

    ACE_DEBUG((LM_DEBUG,
              ACE_TEXT("Stopped host communication.\n")));
    m_comm_mngr->finish();

    m_dll.close();

    ACE_OS::sleep(2);                   // sync. end of managers

    ACE::fini();

    return BEE_SUCCESS;
}

//-----------------------------------------------------------------------------
// Save variables to database.
//-----------------------------------------------------------------------------
int JGEquipment::save(void * parm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::save");
    ACE_UNUSED_ARG(parm);

    // Connect & update database.
    DBConnection::GetDefaultConnection().Connect(m_dsn.c_str());

    TRACE_DEBUG((_TX("DBVariableElm.\n")));
    DBVariableElm::save(this);

    TRACE_DEBUG((_TX("DBAlarmElm.\n")));
    DBAlarmElm::save(this);

    TRACE_DEBUG((_TX("DBEventElm.\n")));
    DBEventElm::save(this);

    TRACE_DEBUG((_TX("DBReportElm.\n")));
    DBReportElm::save(this);

    TRACE_DEBUG((_TX("DBRptDataElm.\n")));
    DBRptDataElm::save(this);

    TRACE_DEBUG((_TX("DBEvtReportElm.\n")));
    DBEvtReportElm::save(this);

    DBConnection::GetDefaultConnection().Release();

    return BEE_SUCCESS;
}

//-----------------------------------------------------------------------------
//  Loading data
//-----------------------------------------------------------------------------
int JGEquipment::load(void * parm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::load");
    ACE_UNUSED_ARG(parm);

    int result;

    TRACE_DEBUG((_TX("CONNECT DB [%s].\n"), m_dsn.c_str()));

    // Connect & read database.
    DBConnection::GetDefaultConnection().Connect(m_dsn.c_str());

    try
    {
        DBConfigElm::load(this);
        DBVariableElm::load(this);
        if ((result = m_info_mngr->initConfig()) < 0)   // load configuration
        {
            TRACE_ERROR((_TX("configure error.\n")));
            return BEE_ERROR;
        }
        const string& dir = this->getConf(CONF_ROOTPATH);
        if (dir.size() > 0)
        {
            m_rootPath = dir;
        }
        DBIODeviceElm::load(this);
        DBTriggerInfoElm::load(this);
        DBAlarmElm::load(this);
        DBEventElm::load(this);
        DBReportElm::load(this);
        DBRptDataElm::load(this);
        DBEvtReportElm::load(this);
        // DBSpoolElm::load(this);
        DBLimitElm::load(this);
        DBLimitBorderElm::load(this);
        DBTraceElm::load(this);
        DBTraceVarElm::load(this);
        DBSubSystemElm::load(this);
    }
    catch (dtl::DBException ex)
    {
        DBConnection::GetDefaultConnection().Release();
        TRACE_ERROR((_TX("DB Error: %s.\n"), ex.twhat()));
        return BEE_ERROR;
    }

    DBConnection::GetDefaultConnection().Release();

    // Set variables in all managers
    for (size_t i = 0; i < m_managers.size(); i++)
    {
        // link id & pointers
        if ((result = m_managers[i]->init()) < 0)   // link variables
        {
            TRACE_ERROR((_TX("%s init error.\n"), m_managers[i]->charName()));
            return BEE_ERROR;
        }
    }

    // Initial all variables
    if (m_info_mngr->initVariables() < 0)
    {
        TRACE_ERROR((_TX("variables initialized error.\n")));
        return BEE_ERROR;
    }

    // Log file open
    static const BCHAR * _categories[] = { CATEGORY_ALARM, CATEGORY_EVENT, NULL };

    JGLogFileManager * logmngr = JGLogFileManager::instance();
    logmngr->init(_categories);
    logmngr->open();

    return BEE_SUCCESS;
}

//-----------------------------------------------------------------------------
//  Methods for EquipmentModel
//-----------------------------------------------------------------------------
bool JGEquipment::isCommunicating() const
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::isCommunicating");

    return m_comm_mngr->isCommunicating();
}

//-----------------------------------------------------------------------------
bool JGEquipment::isOnline() const
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::isOnline");

    return m_control_mngr->isOnline();
}

//-----------------------------------------------------------------------------
bool JGEquipment::isSpooling() const
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::isSpooling");

    if (m_spool_mngr != NULL)
    {
        return m_spool_mngr->isActive();
    }
    return false;
}

//-----------------------------------------------------------------------------
int  JGEquipment::spool(BS2Message * msg)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::spool");
    if (m_spool_mngr != NULL)
    {
        return m_spool_mngr->input(msg);
    }
    return 0;
}

//-----------------------------------------------------------------------------
int  JGEquipment::communicating()
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::communicating");

    int result = m_comm_mngr->enable();

    // if (m_spool_mngr != NULL)
    // {
    //     if (result >= 0)
    //     {   // Communication OK.
    //         m_spool_mngr->stopSpool();
    //     }
    // }
    return result;
}

//-----------------------------------------------------------------------------
int  JGEquipment::notCommunicating()
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::notCommunicating");

    if (m_spool_mngr != NULL)
    {
        m_spool_mngr->startSpool();
    }
    return m_comm_mngr->disable();
}

//-----------------------------------------------------------------------------
JGManager * JGEquipment::findManager(const string& mngrName)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::findManager");
    return JGManager::instance(mngrName.c_str());
}

//-----------------------------------------------------------------------------
JGProcessManager * JGEquipment::getProcessManager(int modNum)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::getProcessManager");
    ACE_UNUSED_ARG(modNum);
    return m_process_mngr;
}

//-----------------------------------------------------------------------------
//  Get system variables
//-----------------------------------------------------------------------------
const string& JGEquipment::getConf(const string& pname)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::getConf");
    return m_info_mngr->getConf(pname);
}

//-----------------------------------------------------------------------------
JGVariable * JGEquipment::variable(const string& vname)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::variable");
    return m_info_mngr->variable(vname);
}

//-----------------------------------------------------------------------------
JGVariable * JGEquipment::variable(const JGid& vid)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::variable");
    return m_info_mngr->variable(vid);
}

//-----------------------------------------------------------------------------
JGvalue& JGEquipment::value(const string& vname)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::value");
    return m_info_mngr->value(vname);
}

//-----------------------------------------------------------------------------
JGvalue& JGEquipment::value(const JGid& vid)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::value");
    return m_info_mngr->value(vid);
}

//-----------------------------------------------------------------------------
int JGEquipment::sendEvent(JGManager * mngr, const string& evt,
                           JGVariable * arg)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::sendEvent");
    return m_event_mngr->request(mngr, evt, arg);
}

//-----------------------------------------------------------------------------
//  Return identifier format
//-----------------------------------------------------------------------------
int JGEquipment::getIdType()
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::getIdType");
    int form = ATOM_ASCII;
    const string& formStr = this->getConf(CONF_IDENTIFIER_TYPE);
    if (formStr.size() > 0)
    {
        form = b_value::strToFormat(formStr.c_str());
    }
    return form;
}

//-----------------------------------------------------------------------------
// Set clock to plc (Dummy Method)
//-----------------------------------------------------------------------------
int JGEquipment::setClock(struct tm& newtm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::setClock");

#if 0
    return BEE_SUCCESS;
#else
    return m_plc_mngr->setClock(newtm);
#endif

}

//-----------------------------------------------------------------------------
// Get clock from plc (Dummy Method)
//-----------------------------------------------------------------------------
int JGEquipment::getClock(struct tm& rettm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::getClock");

#if 0
    time_t lt;
    time(&lt);
    struct tm * now = localtime(&lt);

    rettm.tm_year = now->tm_year;
    rettm.tm_mon = now->tm_mon;
    rettm.tm_mday = now->tm_mday;
    rettm.tm_hour = now->tm_hour;
    rettm.tm_min = now->tm_min;
    rettm.tm_sec = now->tm_sec;
    rettm.tm_wday = now->tm_wday;

    return BEE_SUCCESS;
#else
    return m_plc_mngr->getClock(rettm);
#endif
}

//-----------------------------------------------------------------------------
//  Initial logging data
//-----------------------------------------------------------------------------
int JGEquipment::init_log(u_long parm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::init_log");
    ACE_UNUSED_ARG(parm);

    if (ACE_LOG_MSG->open(_TX("JYUGEM"), ACE_Log_Msg::LOGGER,
                          ACE_DEFAULT_LOGGER_KEY) != -1)
    {
        ACE_Trace::stop_tracing();   // disable trace
    }

    ACE_DEBUG((LM_DEBUG, ACE_TEXT("***************************************\n")));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("* JYUGEM                              *\n")));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("* Copyright(C) 2001-2003 BEE Co.,Ltd. *\n")));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("***************************************\n")));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("version: %s\n\n"), _versionNum));

    return BEE_SUCCESS;
}

//-----------------------------------------------------------------------------
//  Activate manager objects.
//-----------------------------------------------------------------------------
int JGEquipment::act_managers(JGCommDevice * devptr)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::act_managers");

    // create device
    for (size_t i = 0; i < m_managers.size(); i++)
    {
        m_managers[i]->device(devptr);
        m_managers[i]->open();           // threads activate and loop
    }

    return BEE_SUCCESS;
}

//-----------------------------------------------------------------------------
//  Stop manager's services.
//-----------------------------------------------------------------------------
int JGEquipment::stop_managers(u_long parm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::stop_managers");
    ACE_UNUSED_ARG(parm);

    for (int i = (int)m_managers.size() - 1; i >= 0; i--)
    {
        m_managers[i]->end();           // stop thread with managers
    }

    return BEE_SUCCESS;
}

//------------------------------------------------------------------------------
// Start communication
//------------------------------------------------------------------------------
int JGEquipment::start_comm(u_long parm)
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::start_comm");
    ACE_UNUSED_ARG(parm);

    if (m_device == NULL)
    {
        return BEE_ERROR;
    }

    m_device->open();    // start to receive message
    ACE_OS::sleep(1);

    this->open();        // Start service

    return BEE_SUCCESS;
}

//------------------------------------------------------------------------------
// Start communication in service
//------------------------------------------------------------------------------
int JGEquipment::svc()
{
    TRACE_FUNCTION(TRL_MIDDLE, "JGEquipment::svc");

    //
    // Handshake human interface component
    //
    m_pcReady = m_info_mngr->variable(REG_PC_READY);
    const string& timeStr = m_info_mngr->getConf(CONF_PC_DELAY_TIME);
    int  delayTime = _tcstol(timeStr.c_str(), NULL, 10);

    // Chack stand-by status form PC.
    bool isReady = m_pcReady->getv().getBool();

    // Wait for setting HI Ready flag.
    int cursec = 0;

#if 0
    while (! isReady)
    {   // check pc ready
        ACE_OS::sleep(1);
        cursec++;
        if (cursec >= delayTime)
        {
            break;     // stop to check by force
        }
        isReady = m_pcReady->getv().getBool();
    }
    if (cursec < delayTime)
    {   // Reset pc ready bit
        JGvalue init_val(false);
        m_pcReady->setv(init_val);
    }
#else
    ACE_UNUSED_ARG(delayTime);
    ACE_UNUSED_ARG(isReady);
    ACE_UNUSED_ARG(cursec);
#endif

    // Check ready state in driver
    while (! m_comm_mngr->isReadyDriver())
    {
        ACE_OS::sleep(1);
    }

    if (m_spool_mngr != NULL)
    {
        m_spool_mngr->start();      // Start spool
    }
    m_comm_mngr->start();           // Start communication

    ACE_Reactor::instance()->handle_events();

    TRACE_DEBUG((_TX("Return ......\n")));

    return BEE_SUCCESS;
}

//-----------------------------------------------------------------------------
// Dump
//-----------------------------------------------------------------------------
void JGEquipment::dump() const
{
    TRACE_FUNCTION(TRL_LOW, "JGEquipment::dump");

}

