void FridgeControl::updateTemperature() { double temperature; ACS::Time timestamp; ACS_TRACE("::FridgeControl::updateTemperature"); ACSErr::Completion_var completion; double currRefTemperature; currRefTemperature = m_refTemperature_sp->get_sync(completion.out()); temperature = m_currTemperature_sp->get_sync(completion.out()); // simulate the fridge trying to reach the reference temperature. ACS_SHORT_LOG((LOCAL_LOGGING_LEVEL, "::FridgeControl::updateTemperature. Curr value: %f. Ref: %f", temperature, currRefTemperature)); if(temperature < currRefTemperature) { temperature += 0.1; } else if(temperature > currRefTemperature) { temperature -= 0.1; } m_currTemperature_sp->getDevIO()->write(temperature, timestamp); // push data onto the NC this->loadData(); ACS_SHORT_LOG((LOCAL_LOGGING_LEVEL, "::FridgeControl::updateTemperature. New value: %f", temperature)); }
TYPES::AltazVel NexsimImpl::getVel() throw (CORBA::SystemException){ TYPES::AltazVel velocity; ACSErr::Completion_var completion; velocity.azVel = azmVel()->get_sync(completion.out()); velocity.altVel = altVel()->get_sync(completion.out()); return velocity; }
virtual void runLoop() { if(0 == count) { ACS_SHORT_LOG((LM_INFO, "%s: Started runLoop for thread", getName().c_str())); } //while there are still values that need to be set... if(count < numValues) { try { //change the BACI property's value synchronously ACS_SHORT_LOG((LM_INFO, "%s: Setting rwPattern to %d", getName().c_str(), values[count])); rwPattern_m->set_sync(values[count]); count++; ACSErr::Completion_var completion; prop_m = rwPattern_m->get_sync(completion.out()); cout << "rwPatternProperty: " << prop_m << endl; ACE_OS::sleep(1); } catch(...) { ACS_SHORT_LOG((LM_ERROR,"Error!")); } } else { ACS_SHORT_LOG((LM_INFO, "==> Going to test changing of FF and FM if we have a previous alarm.")); // first heaving an alarm comp_m->changeAlarmFFFM("UserDefinedFF", "UserDefinedFM"); // reset all alarms ACS_SHORT_LOG((LM_INFO, "==> Going to test changing of FF and FM if we do not have a previous alarm.")); ACS_SHORT_LOG((LM_INFO, "==> First we reset all alarms an wait that are actaully cleared.")); ACS_SHORT_LOG((LM_INFO, "%s: Setting rwPattern to %d", getName().c_str(), 2)); rwPattern_m->set_sync(2); ACE_OS::sleep(2); //we have to wait that alarm is actually cleaned ACS_SHORT_LOG((LM_INFO, "==> After resting alarms we set new FF FM")); comp_m->changeAlarmFFFM("AnotherUserDefinedFF", "AnotherUserDefinedFM"); ACS_SHORT_LOG((LM_INFO, "==> Generate an alarm after we have changed FF, FM.")); ACS_SHORT_LOG((LM_INFO, "%s: Setting rwPattern to %d", getName().c_str(), 1)); rwPattern_m->set_sync(1); setStopped(); ACS_SHORT_LOG((LM_INFO, "%s: Stopped thread", getName().c_str())); } }
void FridgeControl::cleanUp() { ACS_TRACE("::FridgeControl::cleanUp"); //turn it off before destroying it ACSErr::Completion_var completion; if((m_controlLoop_p!=0) && (powerStatus()->get_sync(completion.out())!=FRIDGE::OFF)) { off(); } // Here we have to stop all threads getContainerServices()->getThreadManager()->stopAll(); // In the past this was done in the CharacteristicComponentImpl::cleanUp(); // As required by the CharacteristicComponentImpl class, // I call explicitly the cleanUp() of the parent class. // This makes sure that all threads are stopped and the // Component's state set. // Depending on what resources are used by a class implementing a // Component and by the implementation of the parent class (if it does // not inherit directly from acscomponent::ACSComponentImpl // or baci:: CharacteristicComponentImpl) it might be // necessary to call the cleanuUp() method of the base class // AFTER having released resources allocated by the current class. // This is demonstrated in this example where we want to make sure // that the powerStatus is FRIDGE::OFF before letting the // cleanUp() of the base class stopping all the // threads, including the one that regulates the temperature. // For an example where the cleanUp() of the parent class // is called before any other step, see the Building class. // Always check the documentation of the parent class // and consider what resources are allocated by this class // to extablish the requirements for the execution of lifecycle // chained methods. // clean-up associated with NC if (m_FridgeSupplier_p != 0) { m_FridgeSupplier_p->disconnect(); m_FridgeSupplier_p=0; } }
// Door check-substate method // Checks for the device's substate. If the device is busy it returns // en error. (Note: the purpose of this function is to show how to handle // local error information.) void Door::checkSubstate (CompletionImpl *&error_p) { try { // Get substate ACS_TRACE("::Door::checkSubstate"); ACSErr::Completion_var completion; CORBA::Long substate = m_substate_sp->get_sync(completion.out()); if ( (substate == DOOR_OPENING) || (substate == DOOR_CLOSING) ) { error_p = new ACSErrTypeCommon::FileNotFoundCompletion(__FILE__, __LINE__, "checkSubstate", ACSErr::Error); return; } } catch(...) { ACS_SHORT_LOG((LM_ERROR,"::Door::checkSubstate")); } error_p = new ACSErrTypeOK::ACSErrOKCompletion();//no error }
int main(int argc, char *argv[]) { if (argc<4) { ACE_OS::printf ("usage: testClient <server_name> <depth> <isError> [iteration]\n"); return -1; }//if // create logging proxy LoggingProxy m_logger (0, 0, 31, 0); LoggingProxy::init (&m_logger); CORBA::ORB_var orb; ACS_TEST_INIT_CORBA; // init ACS error system ACSError::init (orb.ptr()); /**************************************/ acserrTest_var test; int depth; sscanf (argv[2], "%d", &depth); bool isErr = *argv[3]-'0'; int iteration=1, i=1; const int size = 20; // max value 1.84 x 10^19 char printBuf[size+1]; if (argc>4) sscanf (argv[4], "%d", &iteration); ACS_DEBUG("main", "****** Test Block *****"); try { ACS_DEBUG("acserrTestClient", "Getting object reference ... "); char fileName[64]; sprintf(fileName, "file://%s.ior", argv[1]); CORBA::Object_var testObj = orb->string_to_object (fileName); ACS_DEBUG("acserrTestClient", "Narrowing it .... "); test = acserrTest::_narrow (testObj.in()); unsigned long long numToPrint; while( iteration >= i ) { ACS_SHORT_LOG((LM_INFO, "Performing test1 (remote call)... (%d/%d)", i, iteration)); ACSErr::ErrorTrace *corbaErrorTrace=0; ErrorTraceHelper *errorTrace=0; // here is also test for converting Completion_var to CompletionImpl CompletionImpl comp; ACSErr::Completion_var tc = test->test (depth, isErr); comp = tc; if (comp.isErrorFree()) { ACS_SHORT_LOG((LM_INFO, "Completion does not contain an error trace")); comp.log(); return 0; } ACS_SHORT_LOG((LM_INFO, "We got Completion that is equal to ACSErrTest0Completion: %d", ACSErrTest0Completion::isEqual(tc))); ACS_SHORT_LOG((LM_INFO, "We got Completion that is NOT equal to ACSErrTest1Completion: %d", ACSErrTest1Completion::isEqual(tc))); errorTrace = comp.getErrorTraceHelper(); ACS_SHORT_LOG((LM_INFO, "Stack depth: %d", errorTrace->getDepth())); comp.log(); ACE_OS::printf( "%s", errorTrace->toString().c_str() ); corbaErrorTrace = &(errorTrace->getErrorTrace()); do { ACS_SHORT_LOG((LM_INFO, "FileName: \"%s\"",errorTrace->getFileName())); ACS_SHORT_LOG((LM_INFO, "LineNumber: \"%d\"",errorTrace->getLineNumber())); ACS_SHORT_LOG((LM_INFO, "Routine: \"%s\"",errorTrace->getRoutine())); ACS_SHORT_LOG((LM_INFO, "HostName: \"%s\"",errorTrace->getHostName())); ACS_SHORT_LOG((LM_INFO, "Process: \"%s\"",errorTrace->getProcessName())); ACS_SHORT_LOG((LM_INFO, "Thread: \"%s\"",errorTrace->getThread())); for (int ii = 0; ii < size; ii++) printBuf[ii] = ' '; printBuf[size] = '\0'; numToPrint = errorTrace->getTimeStamp(); for (int ii = size - 1; ii >= 0; ii--) { printBuf[ii] = numToPrint % 10 + '0'; numToPrint /= 10; if (numToPrint == 0) break; } ACS_SHORT_LOG((LM_INFO, "TimeStamp: \"%s\"",printBuf)); ACS_SHORT_LOG((LM_INFO, "ErrorType: \"%d\"",errorTrace->getErrorType())); ACS_SHORT_LOG((LM_INFO, "ErrorCode: \"%d\"",errorTrace->getErrorCode())); ACS_SHORT_LOG((LM_INFO, "Severity: \"%d\"", errorTrace->getSeverity())); ACS_SHORT_LOG((LM_INFO, "Description: \"%s\"",errorTrace->getDescription())); } while (errorTrace->getNext()!=NULL); i++; } // while iterator >= i } catch( CORBA::Exception &ex ) { ACE_PRINT_EXCEPTION (ex, "EXCEPTION CAUGHT"); return -1; } ACS_SHORT_LOG((LM_INFO, "Test1 performed.")); //test2 i=1; while (i<=iteration) { try { ACS_SHORT_LOG((LM_INFO, "Performing test2 (remote call - exceptions) ... (%d/%d)", i, iteration)); test->testExceptions (depth, isErr); } catch (ACSErr::ACSException &acse) { ACS_SHORT_LOG((LM_INFO, "Catch ACSException !")); ACSError exception (acse); // put CORBA exception (ACSException) into ACSError wrapper exception.log(); } catch (ACSErrTypeTest::ACSErrTest0Ex &_ex) { ACS_SHORT_LOG((LM_INFO, "Catch ACSErrTest0Ex !")); ACSErrTest0ExImpl exorg(_ex); ACE_CString buf = exorg.getMember3(); ACS_SHORT_LOG((LM_INFO, "Members of the caught exception are: %d, %f, %s, %d", exorg.getMember1(), exorg.getMember2(), buf.c_str(), exorg.getMember4())); ACS_SHORT_LOG((LM_INFO, "Caught an exception that is equal to ACSErrTest0ExImpl: %d", ACSErrTest0ExImpl::isEqual(exorg))); ACS_SHORT_LOG((LM_INFO, "Caught an exception that is NOT equal to ACSErrTest1ExImpl: %d", ACSErrTest1ExImpl::isEqual(exorg))); ACSErrTest0ExImpl *ex = new ACSErrTest0ExImpl(_ex, __FILE__, __LINE__, "testClient::main"); ex->log(); // ACSErrTest0Completion c(_ex.errorTrace, __FILE__, __LINE__, "testClient::main-convertion"); // c.log(); delete ex; } catch(CORBA::Exception &__ex) { ACE_PRINT_EXCEPTION (__ex, "EXCEPTION CAUGHT"); return -1; } i++; }//while ACS_SHORT_LOG((LM_INFO, "Test2 performed.")); // test3 (no error) i=1; while (i<=iteration) { try { ACS_SHORT_LOG((LM_INFO, "Performing test3 (no error) ... (%d/%d)", i, iteration)); CompletionImpl comp = test->testNoError (); comp.log(); // test CompletionImpl copy constructor where there is no error CompletionImpl c1(comp); c1.log(); } catch( CORBA::Exception &ex ) { ACE_PRINT_EXCEPTION (ex, "EXCEPTION CAUGHT"); return -1; } i++; }//while ACS_SHORT_LOG((LM_INFO, "Test3 performed.")); // test4 (default error and operator=) try { ACS_SHORT_LOG((LM_INFO, "Performing test4 (default error and operator=)" )); CompletionImpl defaultComp = test->testDefaultError (); defaultComp.log(); CompletionImpl OKComp = test->testNoError (); OKComp.log(); defaultComp = OKComp; defaultComp.log(); } catch( CORBA::Exception &ex ) { ACE_PRINT_EXCEPTION (ex, "EXCEPTION CAUGHT"); return -1; } ACS_SHORT_LOG((LM_INFO, "Test4 performed.")); // test5 ( error completion, assignment and copy constructor) try { ACS_SHORT_LOG((LM_INFO, "Performing test5" )); CompletionImpl comp = test->test(depth, isErr); comp.log(); ACS_SHORT_LOG((LM_INFO, "Performing test5 - copy constructor" )); // test CompletionImpl copy constructor where there is no error CompletionImpl c1(comp); c1.log(); ACS_SHORT_LOG((LM_INFO, "Performing test5 - assignment constructor" )); CompletionImpl OKComp = test->testNoError (); comp = OKComp; comp.log(); comp = c1; comp.log(); } catch( CORBA::Exception &ex ) { ACE_PRINT_EXCEPTION (ex, "EXCEPTION CAUGHT"); return -1; } ACS_SHORT_LOG((LM_INFO, "Test5 performed.")); // test 6 (completion out) try { ACS_SHORT_LOG((LM_INFO, "Performing test6 (completion out)" )); ACSErr::CompletionImpl comp; ACSErr::Completion_var c; // CORBA completion test->testCompletionOut(depth, isErr, c.out()); comp = c; comp.log(); } catch( CORBA::Exception &ex ) { ACE_PRINT_EXCEPTION (ex, "EXCEPTION CAUGHT"); return -1; } ACS_SHORT_LOG((LM_INFO, "Test6 performed (completion out).")); test->shutdown(); ACE_OS::sleep(5); LoggingProxy::done(); return 0; }
// main loop for the DoorThread, which updates the Door's position void DoorThread::runLoop() { // Control loop ACS::Time timestamp; // TBD: Error/Exception handling ACSErr::Completion_var completion; // Get current door position CORBA::Double currentPosition = door_p->m_position_sp->get_sync(completion.out()); // Get new position CORBA::Double newPosition = door_p->m_ref_position_sp->get_sync(completion.out()); if (newPosition != currentPosition) { // Simulated control ACS_SHORT_LOG((LM_INFO, "Moving %s ...", door_p->getComponent()->getName())); if (currentPosition < newPosition) { // Set state to CLOSING door_p->m_substate_sp->getDevIO()->write(DOOR_CLOSING, timestamp); currentPosition += CTRL_STEP; if (currentPosition > newPosition) { currentPosition = newPosition; } door_p->m_position_sp->getDevIO()->write(currentPosition, timestamp); ACS_SHORT_LOG((LM_INFO, "Current position = %f", currentPosition )); } else { // Set state to OPENING door_p->m_substate_sp->getDevIO()->write(DOOR_OPENING, timestamp); currentPosition -= CTRL_STEP; if (currentPosition < newPosition) { currentPosition = newPosition; } door_p->m_position_sp->getDevIO()->write(currentPosition, timestamp); ACS_SHORT_LOG((LM_INFO, "Current position = %f", currentPosition )); } } else { // Define and set the state CORBA::Double maxPosition = door_p->m_ref_position_sp->max_value(); CORBA::Double minPosition = door_p->m_ref_position_sp->min_value(); if (currentPosition == minPosition) { door_p->m_substate_sp->getDevIO()->write(DOOR_OPEN, timestamp); } else if (currentPosition == maxPosition) { door_p->m_substate_sp->getDevIO()->write(DOOR_CLOSED, timestamp); } else { door_p->m_substate_sp->getDevIO()->write(DOOR_HALTED, timestamp); } } }
int main(int argc, char *argv[]) { // Checks command-line arguments. if (argc < 2) { ACS_SHORT_LOG((LM_INFO, "Usage: %s <component name> <options>", argv[0])); return -1; } else { ACS_SHORT_LOG((LM_INFO, "Welcome to %s!", argv[0])); } //Creates and initializes the SimpleClient object SimpleClient client; if (client.init(argc,argv) == 0) { ACE_DEBUG((LM_DEBUG,"Cannot init client")); return -1; } else { //Must log into manager before we can really do anything client.login(); } try { //List all components of type "*Mount*" the Manager knows of. ACS_SHORT_LOG((LM_INFO, "Listing all components of type *Mount*")); maci::HandleSeq seq; //See the doxygen documentation for maci.idl to understand what these parameters //are. maci::ComponentInfoSeq_var components = client.manager()->get_component_info(client.handle(), seq, "*", "*Mount*", false); for (CORBA::ULong i = static_cast<CORBA::ULong>(0); i < components->length(); i++) { //just print out all known mount components ACS_SHORT_LOG((LM_INFO,"%s (%s)", components[i].name.in(), components[i].type.in())); } // Now get the specific component we have requested from the command-line ACS_SHORT_LOG((LM_INFO, "Getting component: %s", argv[1])); //getComponent can throw an exception if it fails MOUNT_ACS::Mount_var mount = client.getComponent<MOUNT_ACS::Mount>(argv[1], 0, true); //Prints the descriptor of the requested component ACS_SHORT_LOG((LM_DEBUG, "Requesting descriptor()... ")); ACS::CharacteristicComponentDesc_var descriptor = mount->descriptor(); ACS_SHORT_LOG((LM_DEBUG, "Got descriptor().")); ACS_SHORT_LOG((LM_INFO,"Descriptor:")); ACS_SHORT_LOG((LM_INFO,"\tname: %s", descriptor->name.in())); //Get the reference to the actAz double property ACS_SHORT_LOG((LM_INFO, "Getting component property: %s:actAz", argv[1])); ACS::ROdouble_var actAz = mount->actAz(); if (actAz.ptr() != ACS::ROdouble::_nil()) { //Get the current value of the property synchronously ACSErr::Completion_var completion; CORBA::Double val = actAz->get_sync(completion.out()); ACS_SHORT_LOG((LM_INFO,"Value: %f", val)); //Create the CBdouble property ACS_SHORT_LOG((LM_INFO, "Trying to narrow CB for actAz... ")); MyCBdouble myCallback("actAz"); //Activate it as a CORBA object ACS::CBdouble_var cb = myCallback._this(); ACS_SHORT_LOG((LM_INFO, "OK")); //Invoke the asynchronous method. ACS_SHORT_LOG((LM_INFO, "Call get_async for actAz...")); ACS::CBDescIn desc; actAz->get_async(cb.in(), desc); //returns control immediately //Here some other useful things should be done //while the asyncrhonous reply comes //... //... //... //Enter main loop and stays there for a fixed amount of time (1s) //This is done to give the asynchronous method a chance to finish. ACE_Time_Value tv(1); client.run(tv); }//if } catch(maciErrType::CannotGetComponentExImpl &_ex) // can be thrown by getComponent<..>(...) { _ex.log(); return -1; } catch( CORBA::SystemException &_ex ) // can be thrown by get_component_info { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "main"); corbaProblemEx.setMinor(_ex.minor()); corbaProblemEx.setCompletionStatus(_ex.completed()); corbaProblemEx.setInfo(_ex._info().c_str()); corbaProblemEx.log(); return -1; } catch(...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "main"); uex.log(); return -1; }//try-catch //Another try section where we release our component and logout from the Manager try { ACS_SHORT_LOG((LM_INFO,"Releasing...")); client.releaseComponent( argv[1]); client.logout(); } catch(maciErrType::CannotReleaseComponentExImpl &_ex) { _ex.log(); return -1; } catch(...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "main"); uex.log(); return -1; }//try-catch //sleep for 3 sec to allow everytihng to cleanup and stabilize //so that the tests can be determinitstic. ACE_OS::sleep(3); return 0; }
/* * Main procedure */ int main(int argc, char *argv[]) { //Checks command-line arguments. if (argc < 2) { ACS_SHORT_LOG((LM_INFO, "Usage: %s <component name> <options>", argv[0])); return -1; } else { ACS_SHORT_LOG((LM_INFO, "Welcome to %s!", argv[0])); } //Creates and initializes the SimpleClient object SimpleClient client; if (client.init(argc,argv) == 0) { ACE_DEBUG((LM_DEBUG,"Cannot init client")); return -1; } else { //Must log into manager before we can really do anything client.login(); } //Create an instance of our user-defined callback class MyCBdouble myCallback("refTemp"); try { //Get the specific component we have requested on the command-line FRIDGE::FridgeControl_var fridge = client.getComponent<FRIDGE::FridgeControl>(argv[1], 0, true); //Get one of the component's BACI properties ACS::RWdouble_var refTemperature = fridge->refTemperature(); if (refTemperature.ptr() != ACS::RWdouble::_nil()) { ACSErr::Completion_var completion; //Just synchronously reading the value of refTemp CORBA::Double val = refTemperature->get_sync(completion.out()); ACS_SHORT_LOG((LM_INFO,"Value: %f", val)); //Activate the callback as a CORBA object ACS::CBdouble_var cb = myCallback._this(); ACS_SHORT_LOG((LM_INFO, "OK")); ACS::CBDescIn desc; desc.id_tag = 2; ACS_SHORT_LOG((LM_INFO, "Trying to create monitor for refTemperature...")); //Create the actual monitor ACS::Monitordouble_var md = refTemperature->create_monitor(cb.in(), desc); if (md.ptr() != ACS::Monitordouble::_nil()) { ACS_SHORT_LOG((LM_INFO, "OK")); //Set the timer trigger to one second. md->set_timer_trigger(10000000); } else { ACS_SHORT_LOG((LM_INFO, "Failed")); } //Give the callback some time to run. ACE_Time_Value time(20); client.run(time); //Must explicitly destroy the callback before exiting md->destroy(); //Give the callback time to be really destroyed ACE_OS::sleep(15); } } catch(maciErrType::CannotGetComponentExImpl &_ex) { _ex.log(); return -1; } catch(...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "main"); uex.log(); return -1; }//try-catch try { //Must release components and logout from manager ACS_SHORT_LOG((LM_INFO,"Releasing...")); client.releaseComponent(argv[1]); client.logout(); } catch(maciErrType::CannotReleaseComponentExImpl &_ex) { _ex.log(); return -1; } catch(...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "main"); uex.log(); return -1; }//try-catch // sleep for 3 sec. ACE_OS::sleep(3); return 0; }
int main(int argc,char* argv[]) { // create instance of SimpleClient and init() it. SimpleClient ci; if(ci.init(argc,argv) == 0) { ACE_DEBUG((LM_DEBUG,"Cannot init client")); return -1; } ci.login(); try { // get reference to Clock device CORBA::Object_var obj = ci.get_object("CLOCK1",0,true); if(CORBA::is_nil(obj.in())) { return -1; } // narrow object to obtain Clock reference acstime::Clock_var dev = acstime::Clock::_narrow(obj.in()); if (CORBA::is_nil(dev.in())) { std::cerr << "Nil Clock reference" << std::endl; return -1; } //--------------------------------------------------------------- ACSErr::Completion_var completion; ACSErr::Completion* c; int rtnVal; // get pointer to array2TAI Property ACS::RWlong_ptr p_a2t = dev->array2TAI(); for (int i = 0; i < 200; i = (i + 1) * 2) { // set array2TAI value c = p_a2t->set_sync(i); if (c->code == 0) cout << "Set array2TAI=" << i << endl; else cout << "ERROR array2TAI=" << c->code << endl; // get array2TAI value rtnVal = p_a2t->get_sync(completion.out()); if (completion->code != 0) cout << "ERROR array2TAI get=" << completion->code << endl; else { cout << "Got array2TAI=" << rtnVal << endl; if (i != rtnVal) cout << "ERROR array2TAI get != set" << endl; } } // get pointer to TAI2UTC Property ACS::RWlong_ptr p_t2u = dev->TAI2UTC(); for (int i = 0; i < 200; i = (i + 1) * 2) { // set TAI2UTC value c = p_t2u->set_sync(i); if (c->code == 0) cout << "Set TAI2UTC=" << i << endl; else cout << "ERROR TAI2UTC=" << c->code << endl; // get TAI2UTC value rtnVal = p_t2u->get_sync(completion.out()); if (completion->code != 0) cout << "ERROR TAI2UTC get=" << completion->code << endl; else { cout << "Got TAI2UTC=" << rtnVal << endl; if (i != rtnVal) cout << "ERROR TAI2UTC get != set" << endl; } } } catch( CORBA::Exception &ex ) { ACE_PRINT_EXCEPTION(ex,"Error!"); ci.logout(); return -1; } ci.logout(); return 0; }