T. Herlin
28/05/96
IC0 WS classes derived from: evh, fnd and oslx
Why Framework ?
Supported ICS standard commands:
Adding CONFIG command to IC0
#include "ic0SERVER.h" // Example of a simple sub-class of ic0SERVER // A evh callback for the command CONFIG is added. class testSERVER : public ic0SERVER { public: testSERVER(const dbSYMADDRESS dbRef, ccsPROCNAME chkServerName, ccsPROCNAME simServerName, vltINT32 lcuNum, ic0lcuSERVER *lcuServers, char *dictionary, char *alias); evhCB_COMPL_STAT ConfigCB(msgMESSAGE &msg, void *udata); evhCB_COMPL_STAT ConfigReplyCB(msgMESSAGE &msg, void *udata); }; testSERVER::testSERVER(const dbSYMADDRESS dbRef, ccsPROCNAME chkServerName, ccsPROCNAME simServerName, vltINT32 lcuNum, ic0lcuSERVER *lcuServers, char *dictionary, char *alias) : ic0SERVER(dbRef, chkServerName, simServerName, lcuNum, lcuServers, dictionary, alias) { evhMSG_TYPE_KEY key(msgTYPE_COMMAND); evhOBJ_CALLBACK cb(this); // isiServer commands evhHandler->AddCallback(key.Command("CONFIG"), cb.Proc((evhCB_METHOD)ConfigCB)); }
evhCB_COMPL_STAT testSERVER::ConfigCB(msgMESSAGE &msg, void *) { int pNo; // number of parameters char **sPtr; // pointer to string paramter array ic0KEYWORD_LIST *keywordList; // list of keywords handled by command // Check valid system state. // This command is only accepted when system is not in ONLINE if (State() == ic0STATE_ONLINE) { ErrAdd(ic0MOD,ic0ERR_INVALID_STATE, __FILE_LINE__, ic0STATE_LOADED_OR_STANDBY_STR, StateName()); return ErrorReply(msg,ccsFALSE); } // Check the substate of the system. // Here we determine if the systems sub-state allows to handle this // command. if (CheckSubState(msg.Command()) != SUCCESS) return ErrorReply(msg,ccsFALSE); // Parse command parameters into a parameter list structure. // When command parameters are not OK return with failure if (cmdParamList(msg.Command(), msg.Buffer(),strlen(msg.Buffer()), ¶mList, &ErrStack()) == FAILURE) { ErrAdd(ic0MOD,ic0ERR_PARSE_PARAMETERS, __FILE_LINE__,msg.Command()); return ErrorReply(msg); } // Handle "load" parameter and extract configuration filename cmdParamGetStringByName(¶mList, "load", &pNo,(char **)&sPtr, &ErrStack()); if (pNo == 1) { // Processes configuration file sPtr[0] return OkReply(msg); } // Handle individual function configuration cmdParamGetStringByName(¶mList, "function", &pNo,(char **)&sPtr, &ErrStack()); if (pNo != 0) { chkServer->ClearBuffer(ic0chkCHECK_OSLXBUF); // check the keywords if (CheckFunctions("CONFIG", pNo, sPtr, &keywordList, ic0chkCHECK_OSLXBUF) == FAILURE) { // The function must be invalid - reply with the error return ErrorReply(msg); } // Save the original received message in forward object ic0genFORWARD *forwardObj = new ic0genFORWARD(msg); // Install callbacks for: reply, errorReply and callback ccsCOMPL_STAT stat; stat = lcuCmd->Forward("CONFIG", ¶mList, keywordList, forwardObj, (evhCB_METHOD)ConfigReplyCB, (evhCB_METHOD)ErrorCB, // use default (evhCB_METHOD)TimeoutCB); // use default // done with the keywordList delete keywordList; if (stat != SUCCESS) return ErrorReply(msg); // The reply is first sent when the sub-system replies back return evhCB_NO_DELETE; } // If parameters where not catched yet return with error ErrAdd(ic0MOD,ic0ERR_PARSE_PARAMETERS, __FILE_LINE__,"no specified"); return ErrorReply(msg); }
Advantages
Basically a C++ describing the component:
or
class testMOTOR: public ic0COMPONENT { public: testMOTOR(ic0HANDLER *handler, char *keyw, char *cmd = ""); ccsCOMPL_STAT MotorCB(const ic0KEYWORD &keyword, void*); ccsCOMPL_STAT GetKeywords(vltINT32 *no, ic0KEYWORD **keywPtr, msgCMD cmd); protected: ic0KEYWORD motorKeyw; }; /* end class testMOTOR */ class testINS_MODEL: public ic0INS_MODEL { public: testINS_MODEL(); ccsCOMPL_STAT InsModeCB(const ic0KEYWORD &keyword, void*); ccsCOMPL_STAT NewKeywordList(ic0KEYWORD_LIST *list, msgCMD cmd); ccsCOMPL_STAT GetKeywords(vltINT32 *no, ic0KEYWORD **keywPtr, msgCMD cmd); private: ic0DEBUG debug; ic0KEYWORD modeKeyw; }; testINS_MODEL::testINS_MODEL() : modeKeyw("INS.MODE UNKNOWN") { ic0KEYW_KEY key(""); ic0TRIGGER_OBJ trigger(this); // Add a INS.MODE keyword trigger handler->AddTrigger(key.Keyword("INS.MODE"), trigger.Proc((ic0TRIGGER_PROC)InsModeCB)); // Add some motor components to the instrument model Add(*(new testMOTOR(handler,"INS.OPTI-1"))); Add(*(new testMOTOR(handler,"INS.OPTI-2"))); Add(*(new testMOTOR(handler,"INS.OPTI-3"))); } testMOTOR::testMOTOR(ic0HANDLER *handler, char *keyw, char *cmd) { char newKeyword[32]; Id(keyw); // Store the keyword in the device - used as reference strcpy(deviceType,"MOTOR"); // store the device type ic0KEYW_KEY key(""); ic0TRIGGER_OBJ trigger(this); handler->AddTrigger(key.Keyword(keyw).Command(cmd),// Add INS.OPTI-i trigger.Proc((ic0TRIGGER_PROC)MotorCB)); sprintf(newKeyword,"%s.NO", keyw);// reg. INS.OPTI-i.NO keyword trigger handler->AddTrigger(key.Keyword(newKeyword).Command(cmd), trigger.Proc((ic0TRIGGER_PROC)MotorCB)); sprintf(newKeyword,"%s.ID", keyw);// reg. INS.OPTI-i.ID keyword trigger handler->AddTrigger(key.Keyword(newKeyword).Command(cmd), trigger.Proc((ic0TRIGGER_PROC)MotorCB)); } ccsCOMPL_STAT testMOTOR::MotorCB(const ic0KEYWORD &keyword, void*) { Valid(ccsTRUE);// Device function is valid - flag to indicate for the model motorKeyw = keyword;// assign the keyword to the device keyword return SUCCESS; }
Classes witout C++ - how ?
Library myIcs { Module myDev } Module myDev { Description { Simple device build with egen } Environment myENV // environments in this module Process myPROC // processes in this module Class myMANAGER // my device manager Class mySW_DEVICES // Class myDEVICE // software device } Environment myENV { Process myPROC myServer } Process myPROC { Class myMANAGER myManager } Class myMANAGER { Id 201 Interface { inherit ic0devMANAGER Exception Dummy { Type Severe Format "Dummy error" } } Implementation { CodeType CI Attribute mySW_DEVICES swDevices // all SW devices } } Class mySW_DEVICES { Id 203 Implementation { inherit ic0devCONTAINER CodeType C Attribute myDEV dev1 Attribute myDEV dev2 Attribute myDEV dev3 } } Class myDEVICE { Id 310 Interface { inherit ic0devSOFT Exception ReadOldb { Type Severe Format "Device %s: Unable to read %s from OLDB." } } Configuration { // Database decription of device Attribute string<16> Id Attribute int32 myNum Attribute Table myTable[1] { string<256> myName string<32> mydevice uint32 value } } Implementation { CodeType C // Overloaded LCC Software Device user functions Service UsrInit Inherit Service UsrSelfTest Inherit Service UsrTest Inherit Service Setup Inherit } } // _o0o_
IMPROVEMENTS