00001 #include <stdlib.h>
00002 #include "cmwfwList.h"
00003 #include "cmwfwTypes.h"
00004 #include "cmwfwPoller.h"
00005 #include "cmwfwIOValue.h"
00006 #include "cmwfwIOPMapper.h"
00007 #include "cmwfwDeviceServer.h"
00008 #include "cmwfwDeviceAdapter.h"
00009 #include "cmwfwSubscribtionManager.h"
00010
00011
00012 #define FILE "source file:cmwfwDeviceServer.cc"
00013 #define ID "Contact Steen JENSEN, PS/CO"
00014 #define PROGRAM "Middleware server framework"
00015 #define T(a,b,c,d,e) TRACE(a,"%s(%s): %s %s %s %s\n",myname,FILE,b,c,d,e)
00016 #define E(a,b,c,d) ERROR("%s:%s(%s):ERROR: %s %s %s %s - %s\n",PROGRAM,myname,FILE,a,b,c,d,ID)
00017
00018
00019
00020 extern cmwfwIOPMapper framework_iop_mapper;
00021
00032 bool cmwfwDeviceServer::server_exists = false;
00033 cmwfwDeviceServer::cmwfwDeviceServer(const char* srvName,
00034 int argc,
00035 char**argv):cmwfwDeviceServerBase(srvName){
00036 char* myname = "cmwfwDeviceServer::cmwfwDeviceServer";
00037 T(CMWFW_TRACE_CALLS,"Entering","","","");
00038
00039 if(!server_exists){
00040 T(CMWFW_TRACE_SERVER,"Registering server","","","");
00041 server_exists = true;
00042 framework_iop_mapper.reg(*this);
00043 iovalues = new iov_list_type;
00044 if(!iovalues)heaperr(41);
00045 my_argc = argc;
00046 my_argv = argv;
00047 }
00048 else{
00049 E("Only one device server instance supported","","","");
00050 throw cmwfwIOError("",0,"No support for multiple device server instances");
00051 exit(-1);
00052 };
00053 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00054 };
00055
00056
00057
00067 cmwfwDeviceServer::~cmwfwDeviceServer(){
00068
00069 char * myname = "cmwfwDeviceServer::~cmwfwDeviceServer";
00070 T(CMWFW_TRACE_CALLS,"Entering","","","");
00071
00072 bool useMutex = false;
00073 cmwfwIOValue* tmp_iop = 0;
00074 if(iovalues){
00075 T(CMWFW_TRACE_SERVER,"Clearing subscriptions","","","");
00076 iovalues->lock();
00077 iovalues->resetCurrent(false);
00078 iovalues->getFirst(&tmp_iop,useMutex);
00079 while(tmp_iop){
00080 delete tmp_iop;
00081 iovalues->getNext(&tmp_iop,useMutex);
00082 };
00083 delete iovalues;
00084 };
00085 T(CMWFW_TRACE_SERVER,"Unregistering device server","","","");
00086 framework_iop_mapper.unreg(*this);
00087 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00088 };
00089
00090
00091
00092
00102 void cmwfwDeviceServer::shutdownHook(){
00103 char * myname = "cmwfwDeviceServer::shutDownHook";
00104 T(CMWFW_TRACE_CALLS,"Entering","","","");
00105 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00106 };
00107
00108
00109
00110
00120 void cmwfwDeviceServer::Start(){
00121
00122 char* myname = "cmwfwDeviceServer::Start";
00123 T(CMWFW_TRACE_CALLS,"Entering","","","");
00124
00125 T(CMWFW_TRACE_SERVER,"Initializing device adapter","","","");
00126 framework_iop_mapper.getAdapter(cmwfwIOPoint("","","",""))->init();
00127
00128
00129 try{
00130 T(CMWFW_TRACE_SERVER,"Starting CORBA","","","");
00131 this->runServer();
00132 }
00133 catch(cmwfwInternalError& ie){
00134 int i = ie.getLine();
00135 char cp[30];
00136 itoa(i,cp);
00137 E(ie.getFile()," line ",cp,ie.getMessage());
00138 throw;
00139 }
00140 catch(cmwfwException& e){
00141 E(e.getType()," caught a server startup, saying ",e.getMessage(),"");
00142 throw;
00143 }
00144 catch(...){
00145 E("Unhandled exception caught at server startup","","","");
00146 throw;
00147 };
00148 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00149 };
00150
00151
00161 cmwfwData* cmwfwDeviceServer::get(const cmwfwIOPoint& iop,
00162 const cmwfwData& ctx){
00163 char* myname = "cmwfwDeviceServer::get";
00164 T(CMWFW_TRACE_CALLS,"Entering","","","");
00165
00166 cmwfwData* data = 0;
00167 cmwfwDeviceAdapter* adp_ptr = framework_iop_mapper.getAdapter(iop);
00168
00169 if(!adp_ptr){
00170 char errmess[50] = "No adapter found for ";
00171 strcat(errmess,iop.getDeviceName());
00172 E(errmess,"","","");
00173 throw cmwfwBadParameter(errmess);
00174 T(CMWFW_TRACE_CALLS,"Returning - no adapter","","","");
00175 return 0;
00176 };
00177
00178
00179 try{
00180 data = adp_ptr->cmwfw_get(iop, ctx);
00181 }
00182 catch(cmwfwInternalError& ie){
00183 int i = ie.getLine();
00184 char cp[30];
00185 itoa(i,cp);
00186 E(ie.getFile()," line ",cp,ie.getMessage());
00187 throw ie;
00188 return 0;
00189 }
00190 catch(cmwfwBadParameter& bp){
00191 E("Caught ",bp.getType()," saying ",bp.getMessage());
00192 throw bp;
00193 return 0;
00194 }
00195 catch(cmwfwIOError& ioe){
00196 E(ioe.getType(),ioe.getCategory(),ioe.getMessage(),"");
00197 throw ioe;
00198 return 0;
00199 }
00200 catch(cmwfwException& e){
00201 E("Caught cmwfwException: ",e.getType()," saying ",e.getMessage());
00202 throw e;
00203 return 0;
00204 }
00205 catch(...){
00206 E("Caught unhandled exception","","","");
00207 throw;
00208 return 0;
00209 };
00210
00211 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00212 return data;
00213 };
00214
00215
00225 void cmwfwDeviceServer::set(const cmwfwIOPoint& iop,
00226 const cmwfwData& ctx,
00227 const cmwfwData& value){
00228 char* myname = "cmwfwDeviceServer::set";
00229 T(CMWFW_TRACE_CALLS,"Entering","","","");
00230
00231 cmwfwDeviceAdapter* adp_ptr = framework_iop_mapper.getAdapter(iop);
00232
00233 if(!adp_ptr){
00234 char errmess[50] = "No adapter found for ";
00235 strcat(errmess,iop.getDeviceName());
00236 E(errmess,"","","");
00237 throw cmwfwBadParameter(errmess);
00238 T(CMWFW_TRACE_CALLS,"Returning - no adapter","","","");
00239 return;
00240 };
00241
00242 try{
00243 adp_ptr->set(iop, ctx, value);
00244 }
00245 catch(cmwfwInternalError& ie){
00246 int i = ie.getLine();
00247 char cp[30];
00248 itoa(i,cp);
00249 E(ie.getFile()," line ",cp,ie.getMessage());
00250 throw;
00251 }
00252 catch(cmwfwBadParameter& bp){
00253 E("Caught ",bp.getType()," saying ",bp.getMessage());
00254 throw;
00255 }
00256 catch(cmwfwIOError& ioe){
00257 E(ioe.getType(),ioe.getCategory(),ioe.getMessage(),"");
00258 throw;
00259 }
00260 catch(cmwfwException& e){
00261 E("Caught cmwfwException: ",e.getMessage(),"","");
00262 }
00263 catch(...){
00264 E("Caught unhandled exception","","","");
00265 };
00266 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00267 };
00268
00269
00279 void cmwfwDeviceServer::monitorOn(const cmwfwIOPoint& iop,
00280 cmwfwValueChangeListener* listener){
00281 char* myname = "cmwfwDeviceServer::monitorOn";
00282 T(CMWFW_TRACE_CALLS,"Entering","","","");
00283
00284 char* cs = iop.getCycleSelector();
00285 char* dn = iop.getDeviceName();
00286 if(!dn)
00287 throw cmwfwBadParameter("monitorOn: Missing device name");
00288 cmwfwDeviceAdapter* adp_ptr = framework_iop_mapper.getAdapter(iop);
00289 cmwfwPoller* pol_ptr = 0;
00290 cmwfwForwarder* frwd_ptr = 0;
00291 cmwfwIOValue* iov_ptr = 0;
00292
00293 if(cs)T(CMWFW_TRACE_CLIENTS,"IOPoint ",dn,":",cs);
00294 else T(CMWFW_TRACE_CLIENTS,
00295 "IOPoint ",dn," no cycleselector","");
00296
00297 if(!adp_ptr){
00298 char errmess[50] = "No adapter found for ";
00299 strcat(errmess,iop.getDeviceName());
00300 E(errmess,"","","");
00301 throw cmwfwBadParameter(errmess);
00302 T(CMWFW_TRACE_CALLS,"Returning - no adapter","","","");
00303 return;
00304 };
00305
00306 adp_ptr->monitorOn(iop);
00307
00308
00309 try{
00310 pol_ptr = (cmwfwPoller*)adp_ptr->getPoller(iop);
00311 frwd_ptr = (cmwfwForwarder*)adp_ptr->getForwarder(iop);
00312
00313 if( (!frwd_ptr) && (!pol_ptr) ){
00314 char errmess[50] = "Subscriptions not supported for ";
00315 strcat(errmess,iop.getDeviceName());
00316 throw cmwfwBadParameter(errmess);
00317 T(CMWFW_TRACE_CALLS,"Returning - no poller nor forwarder","","","");
00318 return;
00319 };
00320
00321 if(pol_ptr){
00322 if(!(pol_ptr->isRunning()))
00323 pol_ptr->run();
00324 };
00325
00326 iovalues->lock();
00327 iov_ptr = getIOValue(iop,false);
00328
00329 if(!iov_ptr){
00330 cmwfwData ctx;
00331 cmwfwData* d = 0;
00332 iov_ptr = new cmwfwIOValue(iop);
00333 if(!iov_ptr)heaperr(318);
00334 iov_ptr->addListener(listener);
00335 try{
00336 d = get(iop,ctx);
00337 }
00338 catch(cmwfwIOError& ioe){
00339 iov_ptr->update(ioe);
00340 if(d)delete d;d=0;
00341 }catch(...){
00342 delete iov_ptr;
00343 if(d)delete d;d=0;
00344 throw;
00345 return;
00346 };
00347 if(d){
00348 iov_ptr->update(*d,DATA_CHANGED);
00349
00350 delete d;
00351 }
00352 iovalues->insert(iov_ptr,false);
00353 if(pol_ptr)
00354 ((cmwfwSubscribtionManager*)pol_ptr)->attach(iop);
00355 if(frwd_ptr)
00356 ((cmwfwSubscribtionManager*)frwd_ptr)->attach(iop);
00357 }
00358 else{
00359 if(iov_ptr->addListener(listener))
00360 iov_ptr->updateNewListener(listener);
00361 }
00362 iovalues->unlock();
00363
00364 }
00365 catch(cmwfwInternalError& ie){
00366 int i = ie.getLine();
00367 char cp[30];
00368 itoa(i,cp);
00369 E(ie.getFile()," line ",cp,ie.getMessage());
00370 throw;
00371 }
00372 catch(cmwfwBadParameter& bp){
00373 E("Caught ",bp.getType()," saying ",bp.getMessage());
00374 throw;
00375 }
00376 catch(cmwfwIOError& ioe){
00377 E(ioe.getType(),ioe.getCategory(),ioe.getMessage(),"");
00378 throw;
00379 }
00380 catch(cmwfwException& e){
00381 E("Caught cmwfwException: ",e.getMessage(),"","");
00382 }
00383 catch(...){
00384 E("Caught unhandled exception","","","");
00385 };
00386 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00387 };
00388
00389
00399 void cmwfwDeviceServer::monitorOff(const cmwfwIOPoint& iop,
00400 cmwfwValueChangeListener* listener){
00401 char* myname = "cmwfwDeviceServer::monitorOff";
00402 T(CMWFW_TRACE_CALLS,"Entering","","","");
00403
00404 char* cs = iop.getCycleSelector();
00405 char* dn = iop.getDeviceName();
00406 if(!dn)
00407 throw cmwfwBadParameter("monitorOff: Missing device name");
00408
00409 cmwfwDeviceAdapter* adp_ptr = framework_iop_mapper.getAdapter(iop);
00410 cmwfwPoller* pol_ptr = 0;
00411 cmwfwForwarder* fwd_ptr = 0;
00412 cmwfwIOValue* iov_ptr = 0;
00413 cmwfwValueChangeListener* vcl_ptr = 0;
00414
00415 if(cs)T(CMWFW_TRACE_CLIENTS,"IOPoint ",dn,":",cs);
00416 else T(CMWFW_TRACE_CLIENTS,
00417 "IOPoint ",dn," no cycleselector","");
00418
00419 if(!adp_ptr){
00420 char* m = "Communication not possible for ";
00421 char* is = generateIOPString(iop);
00422 char* msg = new char[strlen(m)+strlen(is)+2];
00423 if(!msg)heaperr(378);
00424 msg[0] = 0;
00425 strcat(msg,m);
00426 strcat(msg,is);
00427 E(msg,"","","");
00428 cmwfwBadParameter bp(msg);
00429 delete[] is;
00430 delete[] msg;
00431 throw bp;
00432 T(CMWFW_TRACE_CALLS,"Returning - no adapter","","","");
00433 return;
00434 };
00435
00436 try{
00437 pol_ptr = (cmwfwPoller*)adp_ptr->getPoller(iop);
00438 fwd_ptr = (cmwfwForwarder*)adp_ptr->getForwarder(iop);
00439
00440 if((!pol_ptr)&&(!fwd_ptr)){
00441 char* m = "Subscriptions no supported for ";
00442 char* is = generateIOPString(iop);
00443 char* msg = new char[strlen(m)+strlen(is)+2];
00444 if(!msg)heaperr(398);
00445 msg[0] = 0;
00446 strcat(msg,m);
00447 strcat(msg,is);
00448 cmwfwBadParameter bp(msg);
00449 delete[] is;
00450 delete[] msg;
00451 throw bp;
00452 T(CMWFW_TRACE_CALLS,"Returning - no poller nor forwarder","","","");
00453 return;
00454 };
00455
00456 iovalues->lock();
00457 iov_ptr = getIOValue(iop,false);
00458 if(iov_ptr){
00459 iov_ptr->removeListener(listener);
00460 if(iov_ptr->hasNoListeners()){
00461 if(pol_ptr)
00462 ((cmwfwSubscribtionManager*)pol_ptr)->detach(iop);
00463 if(fwd_ptr)
00464 ((cmwfwSubscribtionManager*)fwd_ptr)->detach(iop);
00465 iovalues->remove(iov_ptr,false);
00466 delete iov_ptr;
00467 };
00468 iovalues->unlock();
00469 adp_ptr->monitorOff(iop);
00470 }
00471 else{
00472 iovalues->unlock();
00473 };
00474 }
00475 catch(cmwfwInternalError& ie){
00476 int i = ie.getLine();
00477 char cp[30];
00478 itoa(i,cp);
00479 E(ie.getFile()," line ",cp,ie.getMessage());
00480 throw;
00481 }
00482 catch(cmwfwBadParameter& bp){
00483 E("Caught ",bp.getType()," saying ",bp.getMessage());
00484 throw;
00485 }
00486 catch(cmwfwIOError& ioe){
00487 E(ioe.getType(),ioe.getCategory(),ioe.getMessage(),"");
00488 throw;
00489 }
00490 catch(cmwfwException& e){
00491 E("Caught cmwfwException: ",e.getMessage(),"","");
00492 }
00493 catch(...){
00494 E("Caught unhandled exception","","","");
00495 };
00496 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00497 };
00498
00499
00500
00512 cmwfwIOValue* cmwfwDeviceServer::getIOValue(const cmwfwIOPoint& iop,
00513 bool useMutex){
00514 char * myname = "cmwfwDeviceServer::getIOValue";
00515 T(CMWFW_TRACE_CALLS,"Entering","","","");
00516
00517 bool stat = false;
00518 cmwfwIOValue* iov_ptr = 0;
00519 cmwfwIOPoint tmp_iop("","","",0);
00520
00521
00522 if(useMutex)
00523 iovalues->lock();
00524
00525 iovalues->resetCurrent(false);
00526 stat = iovalues->getFirst(&iov_ptr,false);
00527 if(stat){
00528 iov_ptr->getIOPoint(tmp_iop);
00529 };
00530
00531 while( (stat) && (tmp_iop != iop) ){
00532 stat = iovalues->getNext(&iov_ptr,false);
00533 if(stat)
00534 iov_ptr->getIOPoint(tmp_iop);
00535 };
00536
00537 if(stat){
00538 if(useMutex)
00539 iovalues->unlock();
00540 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00541 return iov_ptr;
00542 };
00543
00544 if(useMutex)
00545 iovalues->unlock();
00546 T(CMWFW_TRACE_CALLS,"Returning - no iovalue","","","");
00547 return 0;
00548 };
00549
00550
00551
00561 cmwfwIOValue* cmwfwDeviceServer::getIOValues(){
00562 char * myname = "cmwfwDeviceServer::getIOValues";
00563 T(CMWFW_TRACE_CALLS,"Entering","","","");
00564
00565 throw cmwfwIOError("RECOVERABLE",0,"getIOValues not implemented");
00566
00567 T(CMWFW_TRACE_CALLS,"Returning - should not be here","","","");
00568 return 0;
00569 };
00570
00571
00572
00582 cmwfwIOPoint* cmwfwDeviceServer::getIOPoints(){
00583 char * myname = "cmwfwDeviceServer::getIOPoints";
00584 T(CMWFW_TRACE_CALLS,"Entering","","","");
00585
00586 throw cmwfwIOError("RECOVERABLE",0,"getIOValues not implemented");
00587
00588 T(CMWFW_TRACE_CALLS,"Returning - should not be here","","","");
00589 return 0;
00590 };
00591
00592
00593
00594
00595 char* cmwfwDeviceServer::generateIOPString(const cmwfwIOPoint& iop){
00596
00597 char* myname = "cmwfwDeviceServer::generateIOPString";
00598 T(CMWFW_TRACE_CALLS,"Entering","","","");
00599
00600 char* cn = iop.getClassName();
00601 char* dn = iop.getDeviceName();
00602 char* pn = iop.getPropertyName();
00603 char* cs = iop.getCycleSelector();
00604 int cnl = strlen(cn);
00605 int dnl = strlen(dn);
00606 int pnl = strlen(pn);
00607 int csl = 0;
00608 if(cs)
00609 csl = strlen(cs);
00610
00611 char* m = new char[cnl+dnl+pnl+csl+2+5];
00612 if(!m)heaperr(1928);
00613 m[0] = 0;
00614 strcat(m,cn);
00615 strcat(m,":");
00616 strcat(m,dn);
00617 strcat(m,":");
00618 strcat(m,pn);
00619 if(cs){
00620 strcat(m,":");
00621 strcat(m,cs);
00622 };
00623 T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00624 return m;
00625 };
00626
00627
00628
00629
00630 void cmwfwDeviceServer::heaperr(int line){
00631 char* myname = "cmwfwDeviceServer";
00632 T(CMWFW_TRACE_CALLS,"Entering","","","");
00633 char l[30];
00634 itoa(line,l);
00635 E("Out of heap in line ",l,"","");
00636 throw cmwfwInternalError(FILE,line,"Out of heap memory");
00637 T(CMWFW_TRACE_CALLS,"Exiting due to heap allocation error","","","");
00638 exit(-1);
00639 };
00640
00641
00642
00643