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
Organizing of database and it's access
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