00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <SessionObject.hxx>
00024
00025 #include <unistd.h>
00026 #include <time.h>
00027 #include <math.h>
00028
00029
00030 using namespace std;
00031 using namespace cmsg;
00032 using namespace codaObject;
00033
00034
00035
00036
00037
00038
00049 SessionObject::SessionObject(const string& udl, const string& Name, const string& Descr, const string &cClass,
00050 const cMsgSubscriptionConfig *scfg) throw(CodaException)
00051 : CodaObject(udl,Name,Descr,cClass,scfg), session("none"),
00052 sessionControlCBD(new cMsgDispatcher<SessionObject>(this,&SessionObject::sessionControlCallback)),
00053 scSubId(NULL), reportingInterval(2.0), reportingThreadId(0), reportingThreadDispatcher(NULL),
00054 sessionFileContent("") {
00055
00056
00057 if(debug!=0)cout << "Entering SessionObject constructor..." << endl;
00058
00059
00060 objectType="SessionObject";
00061
00062
00063
00064 if(debug!=0)cout << "...SessionObject subscribing..." << endl;
00065 try {
00066 rcConn->subscribe(name, "session/control/*", sessionControlCBD, NULL, myscfg);
00067 } catch (cMsgException &e) {
00068 string err = "?SessionObject constructor...unable to subscribe";
00069 cerr << err << endl;
00070 daLogMsg(err,DALOG_ERROR);
00071 throw(CodaException(e.toString()));
00072 } catch (...) {
00073 string err = "?SessionObject constructor...unknown exception, unable to subscribe";
00074 cerr << err << endl;
00075 daLogMsg(err,DALOG_ERROR);
00076 throw(CodaException(err));
00077 }
00078
00079 if(debug!=0)cout << "...leaving SessionObject constructor" << endl;
00080 }
00081
00082
00083
00084
00085
00090 SessionObject::~SessionObject(void) throw() {
00091
00092 if(debug!=0)cout << "Entering SessionObject destructor..." << endl;
00093
00094 handleStopReporting(NULL);
00095
00096 if(sessionControlCBD!=NULL) {
00097 delete(sessionControlCBD);
00098 sessionControlCBD=NULL;
00099 }
00100
00101 if(debug!=0)cout << "...leaving SessionObject destructor" << endl;
00102 }
00103
00104
00105
00106
00107
00115 void SessionObject::sessionControlCallback(cMsgMessage *msg, void* userArg) throw(CodaException) {
00116
00117 string s = msg->getType();
00118 std::transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower);
00119
00120
00121 if(debug!=0)cout << " sessionControlCallback received message, type is " << s << endl;
00122
00123
00124 if(s=="session/control/setsession") {
00125 handleSetSession(msg);
00126
00127 } else if(s=="session/control/getsession") {
00128 sendResponse(msg,name,"rc/response/getSession",session,0);
00129
00130 } else if(s=="session/control/configure") {
00131 handleSessionConfigure(msg);
00132
00133 } else if(s=="session/control/exit") {
00134 handleExit(msg);
00135
00136 } else if(s=="session/control/reset") {
00137 handleSessionReset(msg);
00138
00139 } else if(s=="session/control/startreporting") {
00140 handleStartReporting(msg);
00141
00142 } else if(s=="session/control/stopreporting") {
00143 handleStopReporting(msg);
00144
00145 } else if(s=="session/control/setinterval") {
00146 reportingInterval=atof(msg->getText().c_str());
00147 reportingInterval=MAX(reportingInterval,MIN_REPORTING_INTERVAL);
00148 reportingInterval=MIN(reportingInterval,MAX_REPORTING_INTERVAL);
00149 if(debug!=0)cout << "sessionObject new reporting interval is " << reportingInterval << endl;
00150
00151 } else {
00152
00153 userMsgHandler(msg,userArg);
00154 return;
00155 }
00156
00157 delete(msg);
00158 }
00159
00160
00161
00162
00168 void SessionObject::handleSessionReset(const cMsgMessage *msg) throw(CodaException) {
00169
00170 this->sessionReset(msg->getText());
00171
00172 }
00173
00174
00175
00176
00177
00183 void SessionObject::handleSetSession(const string &newSession) throw(CodaException) {
00184
00185 if(debug!=0)cout << "in SessionObject::handleSetSession" << endl;
00186
00187
00188 if(newSession==session) {
00189 string info = "SessionObject::handleSetSession...new session " + session + " same as old";
00190 cout << info << endl;
00191 daLogMsg(info,DALOG_INFO);
00192 return;
00193 }
00194
00195
00196
00197 try {
00198 if(scSubId!=NULL) {
00199 rcConn->unsubscribe(scSubId);
00200 scSubId=NULL;
00201 }
00202 } catch (cMsgException e) {
00203 string err = "?SessionObject::handleSetSession...unable to unsubscribe";
00204 cerr << err << endl;
00205 daLogMsg(err,DALOG_ERROR);
00206 throw(CodaException(err));
00207 } catch (...) {
00208 string err = "?SessionObject::handleSetSession...unknown exception, unable to unsubscribe";
00209 cerr << err << endl;
00210 daLogMsg(err,DALOG_ERROR);
00211 throw(CodaException(err));
00212 }
00213
00214
00215
00216 if(!setSession(newSession)) {
00217 string err = "?SessionObject::handleSetSession...setSession failed to set new session " + newSession;
00218 cerr << err << endl;
00219 daLogMsg(err,DALOG_ERROR);
00220 return;
00221 }
00222 session=newSession;
00223
00224
00225
00226 try {
00227 scSubId=rcConn->subscribe(session,"session/control/*", sessionControlCBD, NULL, myscfg);
00228 } catch (cMsgException e) {
00229 string err = "?SessionObject::handleSetSession...unable to subscribe";
00230 cerr << err << endl;
00231 daLogMsg(err,DALOG_ERROR);
00232 throw(CodaException(e.toString()));
00233 } catch (...) {
00234 string err = "?SessionObject::handleSetSession...unknown exception, unable to subscribe";
00235 cerr << err << endl;
00236 daLogMsg(err,DALOG_ERROR);
00237 throw(CodaException(err));
00238 }
00239
00240
00241
00242 string info = "SessionObject...switched to new session " + session;
00243 cout << info << endl;
00244 daLogMsg(info,DALOG_INFO);
00245 return;
00246 }
00247
00248
00249
00250
00251
00257 void SessionObject::handleSetSession(const cMsgMessage *msg) throw(CodaException) {
00258 handleSetSession(msg->getText());
00259 }
00260
00261
00262
00263
00264
00270 void SessionObject::handleSessionConfigure(const cMsgMessage *msg) throw(CodaException) {
00271 if(debug==0) cout << "handleSessionConfigure called" << endl;
00272 try {
00273
00274 string fileName = msg->getString("fileName");
00275
00276
00277
00278 if(config==fileName && msg->getInt32("fileChanged")==0) {
00279 return;
00280 }
00281
00282
00283 config = fileName;
00284 cout << "?SessionObject::handleSessionConfigure: new config " << config << endl;
00285
00286
00287 sessionFileContent = msg->getString("fileContent");
00288
00289
00290 sessionConfigure(config, sessionFileContent);
00291
00292 } catch (cMsgException e) {
00293 cout << "?SessionObject::handleSessionConfigure: invalid payload items" << endl;
00294 }
00295
00296 }
00297
00298
00299
00300
00301
00307 void SessionObject::handleExit(const cMsgMessage *msg) throw(CodaException) {
00308 this->exit(msg->getText());
00309 }
00310
00311
00312
00313
00314
00320 void SessionObject::handleStartReporting(const cMsgMessage *msg) throw(CodaException) {
00321
00322 if(debug!=0)cout << "sessionObject handleStartReporting" << endl;
00323
00324 if(reportingThreadDispatcher==NULL) {
00325
00326 reportingThreadDispatcher = new pthreadDispatcher<SessionObject,void*,void*>(this,&SessionObject::reportingThread,NULL);
00327
00328 if(pthread_create(&reportingThreadId,NULL,pthreadDispatcher<SessionObject,void*,void*>::dispatchIt,
00329 (void*)reportingThreadDispatcher)==0) {
00330 pthread_detach(reportingThreadId);
00331 } else {
00332 reportingThreadId=0;
00333 delete(reportingThreadDispatcher);
00334 reportingThreadDispatcher=NULL;
00335 string err = "?SessionObject::handleStartReporting...unable to start reporting thread";
00336 cerr << err << endl;
00337 daLogMsg(err,DALOG_ERROR);
00338 }
00339
00340 } else {
00341 string warn = "?SessionObject::handleStartReporting: attempt to start a second reporting thread ignored";
00342 cerr << warn << endl;
00343 daLogMsg(warn,DALOG_WARN);
00344 }
00345 }
00346
00347
00348
00349
00350
00356 void SessionObject::handleStopReporting(const cMsgMessage *msg) throw() {
00357
00358 if(debug!=0)cout << "sessionObject handleStopReporting" << endl;
00359
00360
00361 if(reportingThreadId!=0) {
00362 pthread_cancel(reportingThreadId);
00363 pthread_join(reportingThreadId,NULL);
00364 reportingThreadId=0;
00365 }
00366
00367
00368 if(reportingThreadDispatcher!=NULL) {
00369 delete(reportingThreadDispatcher);
00370 reportingThreadDispatcher=NULL;
00371 }
00372
00373 }
00374
00375
00376
00377
00378
00382 void *SessionObject::reportingThread(void*) {
00383
00384 if(debug!=0)cout << "Entering sessionObject reportingThread" << endl;
00385
00386
00387 timespec t;
00388 double d;
00389 int msec;
00390
00391
00392
00393 while(true) {
00394
00395
00396 {
00397 msec=int(modf(reportingInterval,&d)*1000.0);
00398 t.tv_nsec=msec*1000000;
00399 t.tv_sec=int(d);
00400 nanosleep(&t,NULL);
00401
00402
00403
00404 cMsgMessage *msg = new cMsgMessage();
00405 msg->setSubject(name);
00406 msg->setType("rc/report/status");
00407 msg->setText(getStatus());
00408 fillReport(msg);
00409
00410 try {
00411 rcConn->send(msg);
00412 rcConn->flush();
00413 } catch (cMsgException &e) {
00414 string err = e.toString();
00415 cerr << err << endl;
00416 daLogMsg(err,DALOG_ERROR);
00417 } catch (...) {
00418 string err = "SessionObject::reportingThread...unknown exception";
00419 cerr << err << endl;
00420 daLogMsg(err,DALOG_ERROR);
00421 }
00422
00423 delete(msg);
00424 }
00425
00426
00427 pthread_testcancel();
00428 }
00429
00430
00431 return(NULL);
00432 }
00433
00434
00435
00436
00442 void SessionObject::fillReport(cMsgMessage *m) throw() {
00443 m->add("codaClass",getCodaClass());
00444 m->add("state", getState());
00445 m->add("objectType",getObjectType());
00446
00447 }
00448
00449
00450
00456 void SessionObject::daLogMsgFill(cMsgMessage &m) const throw(CodaException) {
00457 CodaObject::daLogMsgFill(m);
00458 m.add("session",getSession());
00459 }
00460
00461
00462
00463
00464
00470 string SessionObject::getSession(void) const throw() {
00471 return(session);
00472 }
00473
00474
00475
00476
00477
00485 bool SessionObject::setSession(const string& newSession) throw(CodaException) {
00486 if(debug!=0)cout << "SessionObject::setSession called for " << newSession << endl;
00487 return(true);
00488 }
00489
00490
00491
00492
00493
00500 bool SessionObject::sessionConfigure(const string& fileName,const string& fileContent) throw(CodaException) {
00501 cout << "SessionObject...dummy configure called" << endl;
00502 return(true);
00503 }
00504
00505
00506
00507
00508
00514 void SessionObject::exit(const string& s) throw(CodaException) {
00515 cout << endl << " *** SessionObject...default exit called ***" << endl << endl;
00516 std::exit(EXIT_SUCCESS);
00517 }
00518
00519
00520
00521
00527 void SessionObject::sessionReset(const string& s) throw(CodaException) {
00528 cout << endl << " *** SessionObject...default reset called ***" << endl << endl;
00529 }
00530
00531
00532
00533