Newer
Older

Graziano Scalamera
committed
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
{
argout->length(complete.size());
for(size_t i=0; i<complete.size(); i++)
(*argout)[i] = Tango::string_dup(complete[i].c_str());
}
else
{
vector<string> out;
//out.push_back(NAME_KEY + string("=") + it->first);
for(size_t arg_i=0; arg_i < argin->length()-1; arg_i++)
{
map<string,string>::iterator it2 = info.find(string((*argin)[arg_i+1]));
if(it2 != info.end())
{
out.push_back(it2->first + string("=") + it2->second);
}
}
argout->length(out.size()/*+1*/);
vector<string>::iterator it3;
size_t i=0;
for(it3=out.begin(); it3!=out.end(); it3++)
{
(*argout)[i] = Tango::string_dup(it3->c_str());
i++;
}
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::get_alarm_info
return argout;
}
//--------------------------------------------------------
/**
* Command ReLoadAll related method
* Description: Re Load all alarms.
*
*/
//--------------------------------------------------------
void AlarmHandler::re_load_all()
{
DEBUG_STREAM << "AlarmHandler::ReLoadAll() - " << device_name << endl;
/*----- PROTECTED REGION ID(AlarmHandler::re_load_all) ENABLED START -----*/
// Add your own code
vector<string> tmp_alm_vec;
alarms.get_alarm_list_db(tmp_alm_vec, saved_alarms, savedlock);//holds write locks savedlock
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
for(const auto &it_al : tmp_alm_vec)
{
bool modify_err=false;
try
{
modify((Tango::DevString)it_al.c_str());
}
catch(Tango::DevFailed &e)
{
INFO_STREAM << __func__ << ": error modifying '" << it_al << "' err='" << e.errors[0].desc << "'";
modify_err=true;
}
if(modify_err)
{
try
{
load((Tango::DevString)it_al.c_str());
}
catch(Tango::DevFailed &e)
{
INFO_STREAM << __func__ << ": error loading '" << it_al << "' err='" << e.errors[0].desc << "'";
}
}
}
/*----- PROTECTED REGION END -----*/ // AlarmHandler::re_load_all
}
//--------------------------------------------------------

Graziano Scalamera
committed
/**
* Method : AlarmHandler::add_dynamic_commands()

Graziano Scalamera
committed
* Description : Create the dynamic commands if any
* for specified device.
*/
//--------------------------------------------------------
void AlarmHandler::add_dynamic_commands()

Graziano Scalamera
committed
{
/*----- PROTECTED REGION ID(AlarmHandler::add_dynamic_commands) ENABLED START -----*/

Graziano Scalamera
committed
// Add your own code to create and add dynamic commands if any
/*----- PROTECTED REGION END -----*/ // AlarmHandler::add_dynamic_commands

Graziano Scalamera
committed
}
/*----- PROTECTED REGION ID(AlarmHandler::namespace_ending) ENABLED START -----*/

Graziano Scalamera
committed
// Additional Methods
/*
* private methods
*/
void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::load_alarm(): Creating Spirit Parser... ->" << alarm_string << endl;

Graziano Scalamera
committed
alarm_parse al_gr(alm); // Construct Spirit grammar
alm.name.clear();
alm.attr_name.clear();
alm.quality = Tango::ATTR_INVALID;
alm.ex_reason=string("NOT_SUBSCRIBED");
alm.ex_desc=string("One or more events not subscribed");
alm.ex_origin.clear();
alm.ts_err_delay = gettime();
alm.ts_err_delay.tv_sec -= errorDelay;

Graziano Scalamera
committed
alm.formula.clear();
alm.msg.clear();

Graziano Scalamera
committed
alm.lev.clear();
alm.grp=0;
alm.to_be_evaluated = false;
alm.on_delay = 0;
alm.off_delay = 0;

Graziano Scalamera
committed
alm.silent_time = -1;
alm.silenced = -1;
alm.cmd_name_a.clear();
alm.cmd_dp_a.clear();
alm.cmd_action_a.clear();
alm.send_arg_a = false;
alm.dp_a = NULL;
alm.cmd_name_n.clear();
alm.cmd_dp_n.clear();
alm.cmd_action_n.clear();
alm.send_arg_n = false;
alm.dp_n = NULL;

Graziano Scalamera
committed
evn.clear();
alm.formula_tree =
//boost::spirit::tree_parse_info< std::string::iterator, factory_t> tmp =
ast_parse<factory_t>(alarm_string.begin(), alarm_string.end(), al_gr, space_p); //parse string s with grammar al_gr, skipping white spaces
if (alm.formula_tree.full)
{
std::transform(alm.name.begin(), alm.name.end(), alm.name.begin(), (int(*)(int))tolower); //transform to lowercase
//replace / with __
if(!alm.name.empty())
{
alm.attr_name = alm.name;
alm.attr_name = std::regex_replace(alm.attr_name, std::regex("/"), "_");

Graziano Scalamera
committed
//std::transform(alm.formula.begin(), alm.formula.end(), alm.formula.begin(), (int(*)(int))tolower); //transform to lowercase: incorrect, state has to be written uppercase
std::transform(alm.lev.begin(), alm.lev.end(), alm.lev.begin(), (int(*)(int))tolower); //transform to lowercase
alm.msg = std::regex_replace(alm.msg, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
alm.url = std::regex_replace(alm.url, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"

Graziano Scalamera
committed
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
if(alm.cmd_name_a.length() > 0)
{
const char *c = alm.cmd_name_a.c_str();
int j = 0;
while (*c) {
if (*c == '/')
j++;
if (j < 3)
alm.cmd_dp_a.push_back(*c);
else if (*c != '/')
alm.cmd_action_a.push_back(*c);
c++;
}
}
if(alm.cmd_name_n.length() > 0)
{
const char *c = alm.cmd_name_n.c_str();
int j = 0;
while (*c) {
if (*c == '/')
j++;
if (j < 3)
alm.cmd_dp_n.push_back(*c);
else if (*c != '/')
alm.cmd_action_n.push_back(*c);
c++;
}
}
alm.silenced = (alm.silent_time > 0) ? 0 : -1; //0: can be silenced, -1: cannot be silenced
DEBUG_STREAM << "Parsing succeeded! ->" << alm.name << endl;
find_event_formula(alm.formula_tree,evn); //populate event list found in this formula
ostringstream dbg_msg;
dbg_msg << "In " << alm.name << " Event =";
for (vector<string>::iterator i = evn.begin(); i != evn.end(); i++)
dbg_msg << *i << ", ";

Graziano Scalamera
committed
DEBUG_STREAM << dbg_msg.str() << endl;
}
o << "AlarmHandler::load_alarm(): Parsing Failed, '" << string(alarm_string.begin(), alm.formula_tree.stop) << "' parsed ok, BUT '" << string(alm.formula_tree.stop, alarm_string.end()) << "' not parsed"; //TODO
DEBUG_STREAM << o.str() << endl;
Tango::Except::throw_exception( \
(const char*)"Parsing Failed!", \
(const char*)o.str().c_str(), \
(const char*)"AlarmHandler::load_alarm()", Tango::ERR);
}

Graziano Scalamera
committed
alm.ts = gettime();
DEBUG_STREAM << "AlarmHandler::load_alarm(): name = '" << alm.name << "'" << endl;
DEBUG_STREAM << " attr_name = '" << alm.attr_name << "'" << endl;

Graziano Scalamera
committed
DEBUG_STREAM << " formula = '" << alm.formula << "'" << endl;
DEBUG_STREAM << " on_delay = '" << alm.on_delay << "'" << endl;
DEBUG_STREAM << " off_delay = '" << alm.off_delay << "'" << endl;

Graziano Scalamera
committed
DEBUG_STREAM << " msg = '" << alm.msg << "'" << endl;
DEBUG_STREAM << " url = '" << alm.url << "'" << endl;

Graziano Scalamera
committed
DEBUG_STREAM << " grp = '" << showbase << hex << alm.grp << "'=" << alm.grp2str() << endl;
DEBUG_STREAM << " silent_time = '" << alm.silent_time << "'" << endl;
DEBUG_STREAM << " silenced = '" << alm.silenced << "'" << endl;
DEBUG_STREAM << " lev = '" << alm.lev << "'" << endl;
DEBUG_STREAM << " action_a = '" << alm.cmd_name_a << "'" << endl;
DEBUG_STREAM << " action_n = '" << alm.cmd_name_n << "'" << endl;
DEBUG_STREAM << " enabled = '" << (alm.enabled ? "1" : "0") << "'" << endl;

Graziano Scalamera
committed
if ((alm.name.empty() == false) && \
(alm.formula.empty() == false) && \
(alm.msg.empty() == false) && \

Graziano Scalamera
committed
((alm.lev==LEV_LOG)||(alm.lev==LEV_WARNING)|| \
(alm.lev==LEV_FAULT)||(alm.lev==LEV_LOWEST)||(alm.lev==LEV_LOW)|| \
(alm.lev==LEV_MEDIUM)||(alm.lev==LEV_HIGH)||(alm.lev==LEV_HIGHEST)||(alm.lev.empty() == true))) {

Graziano Scalamera
committed
alm.stat = S_NORMAL;
alm.ack = ACK;
alm.done = false;
// alm.grp = GR_DEFAULT;
// alm.lev = LEV_DEFAULT;
} else {
ostringstream o;
o << "AlarmHandler::load_alarm(): syntax error in '" << alarm_string << "'";

Graziano Scalamera
committed
WARN_STREAM << o.str() << endl;
Tango::Except::throw_exception( \
(const char*)o.str().c_str(), \
(const char*)"", \
(const char*)"AlarmHandler::load_alarm()", Tango::ERR);

Graziano Scalamera
committed
}
if (alarms.exist(alm.name)) {
ostringstream o;
o << "AlarmHandler::load_alarm(): alarm '" << alm.name << "' already exist";

Graziano Scalamera
committed
WARN_STREAM << o.str() << endl;
Tango::Except::throw_exception( \
(const char*)o.str().c_str(), \
(const char*)o.str().c_str(), \
(const char*)"AlarmHandler::load_alarm()", Tango::ERR);

Graziano Scalamera
committed
}
}
void AlarmHandler::init_alarms(map< string,vector<string> > &alarm_events)

Graziano Scalamera
committed
{
alarms.vlock->readerIn();
if (alarms.v_alarm.empty() == false)
{
for (alarm_container_t::iterator i = alarms.v_alarm.begin(); \
i != alarms.v_alarm.end(); i++)
{
map< string,vector<string> >::iterator f = //looking in map for alarm name as key
// find(alarm_events->begin(), alarm_events->end(), i->name);
alarm_events.find(i->second.name);
if(f == alarm_events.end())
continue; //ERROR: alarm not found in alarm_event map
DEBUG_STREAM << "AlarmHandler::init_alarms(): found Alarm= " << i->second.name << endl;

Graziano Scalamera
committed
for(vector<string>::iterator j = f->second.begin(); \
j != f->second.end(); j++)
{
vector<event>::iterator found = \
find(events->v_event.begin(), events->v_event.end(), (*j));
DEBUG_STREAM << "AlarmHandler::init_alarms(): looking in events table for Event= " << (*j) << endl;

Graziano Scalamera
committed
if (found != events->v_event.end())
{
i->second.insert(found->name);
found->m_alarm.push(i->second.name);
DEBUG_STREAM << "AlarmHandler::init_alarms(): found Event= " << found->name << " <- Alarm= " << i->second.name << endl;

Graziano Scalamera
committed
//break; ???
} /* if */
} /* for */
}
}
alarms.vlock->readerOut();
}
void AlarmHandler::init_events(vector<string> &evn)

Graziano Scalamera
committed
{
if (evn.empty() == false) {
sort(evn.begin(), evn.end());
vector<string>::iterator new_end = \
unique(evn.begin(), evn.end());
while (evn.end() != new_end) {
evn.pop_back();
}
vector<string>::iterator j = evn.begin();
while (j != evn.end()) {
//TODOevents->push_back(event(*j));

Graziano Scalamera
committed
j++;
}
} /* if */
}
void AlarmHandler::add_alarm(alarm_t& a, bool starting)

Graziano Scalamera
committed
{
alarms.push_back(a); //take and release writer vlock
DEBUG_STREAM << "AlarmHandler::add_alarm(): added alarm '" \

Graziano Scalamera
committed
<< a.name << "'" << endl;
alarm_container_t::iterator italm = alarms.v_alarm.find(a.name);
add_AlarmState_dynamic_attribute(italm->second.attr_name);
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(italm->second.attr_name);
italm->second.attr_value = attr_value;
italm->second.attr_name_formula = italm->second.attr_name + string("Formula");
#if _FORMULA_ATTR
add_AlarmFormula_dynamic_attribute(italm->second.attr_name_formula);
Tango::DevString *attr_value_formula = get_AlarmFormula_data_ptr(italm->second.attr_name_formula);
*attr_value_formula = Tango::string_dup(italm->second.formula.c_str());
italm->second.attr_value_formula = attr_value_formula;
#endif

Graziano Scalamera
committed
}
void AlarmHandler::add_event(alarm_t& a, vector<string> &evn) throw(string&)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::add_event(): formula '" << a.formula << "' found " << evn.size() << " events" << endl;

Graziano Scalamera
committed
/*
* get the list of all the events in the formula
*/
for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++)
{
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k == events->v_event.end()) //if not already present
{
string name=*j;
vector<string> context;//TODO
events->add(name, context, UPDATE_PROP, false);//throws exception if already present
}
}

Graziano Scalamera
committed
for (vector<string>::iterator j = evn.begin(); j != evn.end(); j++) {
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end()) {
/*
* the event already exist; push alarm name
* into the per-event alarm list
*/

Graziano Scalamera
committed
a.to_be_evaluated = true;
DEBUG_STREAM << "AlarmHandler::add_event(): '" << *j << "' found, added " \

Graziano Scalamera
committed
<< " alarm '" << a.name << "' to list, valid=" << k->valid << endl;
alarms.vlock->readerIn();
alarm_container_t::iterator l = alarms.v_alarm.find(a.name);
if (l != alarms.v_alarm.end())
{
l->second.insert(*j); //insert event name in set<string> (s_event) in alarm_t
}
else
{
WARN_STREAM << "AlarmHandler::add_event(): error inserting event '" << *j << "' in set of alarm '"

Graziano Scalamera
committed
<< a.name << "'" << endl;
}
alarms.vlock->readerOut();
}
else
{
/*
* new event; add to event table
*/
//event e(*j);
//events->push_back(e);

Graziano Scalamera
committed
/*
* update per-alarm event list
*/
DEBUG_STREAM << "AlarmHandler::add_event(): adding '" << *j \

Graziano Scalamera
committed
<< "' to event list of alarm '" << a.name << "'" << endl;
alarms.vlock->readerIn();
alarm_container_t::iterator l = alarms.v_alarm.find(a.name);
if (l != alarms.v_alarm.end())
{
l->second.insert(*j); //insert event name in set<string> in alarm_t
}
else
{
WARN_STREAM << "AlarmHandler::add_event(): error inserting event '" << *j << "' in set of alarm '"

Graziano Scalamera
committed
<< a.name << "'" << endl;
}
alarms.vlock->readerOut();
/*
* now, for the just-added event

Graziano Scalamera
committed
*/
k = find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end())
{

Graziano Scalamera
committed
//now initialize value of this attribute
try {
Tango::DeviceAttribute attr_value;
attr_value = k->dp->read_attribute(k->attribute);
ecb.extract_values(&attr_value, k->value, k->type, k->read_size);

Graziano Scalamera
committed
k->valid = true;
ostringstream msg;
msg << "AlarmHandler::add_event(): initial values of " << k->name << " = ";

Graziano Scalamera
committed
for(vector<double>::iterator dd=k->value.begin(); dd!=k->value.end(); dd++)
msg << (*dd) << " ";
msg << ", valid=" << k->valid << ends;
DEBUG_STREAM << msg.str() << endl;
//delete attr_value;
} catch(Tango::DevFailed& e

Graziano Scalamera
committed
{
TangoSys_MemStream out_stream;
out_stream << "Failed to read initial value of " << k->name << " = " << e.errors[0].desc << ends;
k->valid = false;
#if TANGO_VER < 611 //if using subscribe stateless, alarm is not removed if it fails the subscription
k->m_alarm.pop(a.name); //remove alarm/formula just added to event

Graziano Scalamera
committed
//events->v_event.pop_back();
events->v_event.erase(k); //remove event just added to event_table
//delete attr_value;
#endif
throw out_stream.str();
} catch(string & e)
{
TangoSys_MemStream out_stream;
out_stream << "Error reading initial value of " << k->name << " = " << e << ends;
k->m_alarm.pop(a.name); //remove alarm/formula just added to event

Graziano Scalamera
committed
//events->v_event.pop_back();
events->v_event.erase(k); //remove event just added to event_table
//delete attr_value;
throw out_stream.str();
}

Graziano Scalamera
committed
}
}
} //for (vector<string>::iterator j = evn.begin(); ...
for(vector<string>::iterator j = evn.begin(); j != evn.end(); j++)
{

Graziano Scalamera
committed
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end()) //if already present

Graziano Scalamera
committed
{
string name=*j;
events->start(name);//throws exception if not found
}
}

Graziano Scalamera
committed
}

Graziano Scalamera
committed
/*
* because called asynchronously by alarm evaluating thread
* will use an alarm to report errors
*/
void AlarmHandler::do_alarm(bei_t& e)

Graziano Scalamera
committed
{
bool changed=true;
int num_changed=0;

Graziano Scalamera
committed
//if (e.name == INTERNAL_ERROR) {
if(e.type == TYPE_TANGO_ERR || e.type == TYPE_GENERIC_ERR)
{

Graziano Scalamera
committed
ostringstream o;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;

Graziano Scalamera
committed
vector<event>::iterator found_ev = \
find(events->v_event.begin(), events->v_event.end(), e.ev_name);
if (found_ev == events->v_event.end())
{
//try to remove network domain and FQDN
string ev_name_str(e.ev_name);
string::size_type pos_slash = ev_name_str.find("tango://");
if (pos_slash != string::npos) //FQDN!!
{
//first remove network domain if any
string::size_type pos_dot = ev_name_str.find(".",8); //look for first . after tango://
string::size_type pos_colon = ev_name_str.find(":",8); //look for first : after tango://
pos_slash = ev_name_str.find('/',8); //look for first / after tango://
if(pos_dot < pos_slash && pos_dot != string::npos && pos_colon != string::npos && pos_slash != string::npos) //dot is in the TANGO_HOST part
{
string ev_name_str_no_domain = ev_name_str.substr(0,pos_dot) + ev_name_str.substr(pos_colon);
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without domain: " << ev_name_str_no_domain;

Graziano Scalamera
committed
found_ev = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str_no_domain);
}
if (found_ev == events->v_event.end() && pos_slash != string::npos)
{
ev_name_str = ev_name_str.substr(pos_slash + 1);//remove FQDN
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without fqdn: " << ev_name_str;

Graziano Scalamera
committed
found_ev = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str);
}
}
if (found_ev == events->v_event.end())
{
/*
* shouldn't happen!!!
*/
ostringstream o;
o << "TANGO Error but event '" \
<< e.ev_name << "' not found in event table!";
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(e.ev_name, gettime(), o.str());
}
}
if(found_ev != events->v_event.end())
{

Graziano Scalamera
committed
found_ev->err_counter++;
if(e.type == TYPE_TANGO_ERR)
found_ev->ex_reason = string("Event_ERROR");
else
found_ev->ex_reason = string("Alarm_ERROR");
found_ev->ex_desc = o.str();
found_ev->ex_origin = e.ev_name;
found_ev->quality = e.quality;
//LOOP ALARMS IN WHICH THIS EVENT IS USED
list<string> m_alarm=found_ev->m_alarm.show();
string found_ev_ex_reason = found_ev->ex_reason;
string found_ev_ex_desc = found_ev->ex_desc;
string found_ev_ex_origin = found_ev->ex_origin;
events->veclock.readerOut();
list<string>::iterator j = m_alarm.begin();
while (j != m_alarm.end())
{
alarms.vlock->readerIn();
alarm_container_t::iterator it = alarms.v_alarm.find(*j);
if(it != alarms.v_alarm.end())
{
if(it->second.ex_reason.empty() && it->second.ex_desc.empty() && it->second.ex_origin.empty())
{
it->second.ack = NOT_ACK;
it->second.ts_err_delay = gettime(); //first occurrance of this error, now begin to wait for err delay
it->second.ex_reason = found_ev_ex_reason;
it->second.ex_reason = found_ev_ex_reason;
it->second.ex_desc = found_ev_ex_desc;
it->second.ex_origin = found_ev_ex_origin;
if((ts.tv_sec - errorDelay) > it->second.ts_err_delay.tv_sec) //error is present and err delay has passed
{
if(!it->second.error)
it->second.is_new = 1;
{
if(!it->second.error)
it->second.is_new = 1;
alarm_t alm = it->second;
alarms.vlock->readerOut();
try
{
Tango::DevErrorList errors(1);
errors.length(1);
errors[0].desc = CORBA::string_dup(alm.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(alm.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(alm.ex_origin.c_str());
Tango::DevFailed except(errors);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": PUSHING EXCEPTION FOR " << alm.attr_name << " " << alm.ex_desc << "-" << alm.ex_reason << "-" << alm.ex_origin << endl;
push_change_event(alm.attr_name, &except);
push_archive_event(alm.attr_name, &except);
}catch(Tango::DevFailed &ex)
{}
}
else
{
alarms.vlock->readerOut();
}
j++;
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway
if(ds_num == 0)
{
//attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false);
struct timeval now;
gettimeofday(&now,NULL);
push_change_event("alarm",(char**)ds,now,Tango::ATTR_WARNING, ds_num, 0, false);
}
else
{
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);
}
push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_change_event("alarmAudible",attr_alarmAudible_read);
push_change_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_archive_event("alarmAudible",attr_alarmAudible_read);
push_archive_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);

Graziano Scalamera
committed
}
return;
}
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": arrived event=" << e.ev_name << endl;
formula_res_t res;

Graziano Scalamera
committed
vector<event>::iterator found = \
find(events->v_event.begin(), events->v_event.end(), e.ev_name);
if (found == events->v_event.end())
{
//try to remove network domain and FQDN
string ev_name_str(e.ev_name);
string::size_type pos_slash = ev_name_str.find("tango://");
if (pos_slash != string::npos) //FQDN!!
{
//first remove network domain if any
string::size_type pos_dot = ev_name_str.find(".",8); //look for first . after tango://
string::size_type pos_colon = ev_name_str.find(":",8); //look for first : after tango://
pos_slash = ev_name_str.find('/',8); //look for first / after tango://
if(pos_dot < pos_slash && pos_dot != string::npos && pos_colon != string::npos && pos_slash != string::npos) //dot is in the TANGO_HOST part
{
string ev_name_str_no_domain = ev_name_str.substr(0,pos_dot) + ev_name_str.substr(pos_colon);
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without domain: " << ev_name_str_no_domain;

Graziano Scalamera
committed
found = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str_no_domain);
}
if (found == events->v_event.end() && pos_slash != string::npos)
{
ev_name_str = ev_name_str.substr(pos_slash + 1);//remove FQDN
//DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event "<< e.ev_name << " not found, trying without fqdn: " << ev_name_str;

Graziano Scalamera
committed
found = \
find(events->v_event.begin(), events->v_event.end(), ev_name_str);
}
}
if (found == events->v_event.end())
{
/*
* shouldn't happen!!!
*/
ostringstream o;
o << "event '" \
<< e.ev_name << "' not found in event table!";
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;

Graziano Scalamera
committed
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
}
}
if (found != events->v_event.end())
{
found->value = e.value;
found->value_string = e.value_string;
found->quality = e.quality;
//found->errors = e.errors;
found->ex_reason = e.ex_reason;
found->ex_desc = e.ex_desc;
found->ex_origin = e.ex_origin;

Graziano Scalamera
committed
found->valid = true;
found->ts = e.ts;
found->type = e.type;
found->read_size = e.read_size;

Graziano Scalamera
committed
found->err_counter = 0;
list<string> m_alarm=found->m_alarm.show();
Tango::TimeVal ts = found->ts;
events->veclock.readerOut(); //do not hold events->veclock in do_alarm_eval which push events
list<string>::iterator j = m_alarm.begin();
while (j != m_alarm.end())
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before do_alarm_eval name=" << *j << " ev=" << e.ev_name << endl;
changed = do_alarm_eval(*j, e.ev_name, ts);
if(changed)
num_changed++;
j++;
}
if(num_changed==0)
{
alarms.vlock->readerIn();
alarm_container_t::iterator ai;
size_t freq_ind = 0;
for (ai = alarms.v_alarm.begin(); ai != alarms.v_alarm.end(); ai++)
{
attr_alarmFrequency_read[freq_ind] = ai->second.freq_counter;
freq_ind++;
}
prepare_alm_mtx->unlock();
push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
return;
prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway
if(ds_num == 0)
{
//attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false);
struct timeval now;
gettimeofday(&now,NULL);
push_change_event("alarm",(char**)ds,now,Tango::ATTR_WARNING, ds_num, 0, false);
}
else

Graziano Scalamera
committed
{
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
}
push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_change_event("alarmAudible",attr_alarmAudible_read);
push_change_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_archive_event("alarmAudible",attr_alarmAudible_read);
push_archive_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event=" << e.ev_name << "NOT FOUND IN EVENT TABLE" << endl;
} /* do_alarm() */
bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ts)
{
bool changed = true;
formula_res_t res;
//alarm_container_t::iterator it = alarms.v_alarm.find(j->first);
alarms.vlock->readerIn();
alarm_container_t::iterator it = alarms.v_alarm.find(alm_name);
if(it != alarms.v_alarm.end())
{
string attr_name = it->second.attr_name;
if(ev_name == "FORCED_EVAL" && !it->second.to_be_evaluated)
{
DEBUG_STREAM << __func__ << ": ev_name=" << ev_name << " -> FORCED_EVAL && !it->second.to_be_evaluated -> changed=false" << endl;
alarms.vlock->readerOut();
return false;
}
if(ev_name != "FORCED_EVAL")
it->second.freq_counter++;
string tmpname=it->first;
string ex_reason = it->second.ex_reason;
string ex_desc = it->second.ex_desc;
string ex_origin = it->second.ex_origin;
prev_error = it->second.error;
if(prev_error)
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before evaluating exception {"<<ex_reason<<","<<ex_desc.length()<<","<<ex_origin<<"}"<<endl;
try {
res = eval_formula(it->second.formula_tree, it->second.attr_values);
it->second.to_be_evaluated = false;
it->second.attr_values.erase(it->second.attr_values.size()-1);
it->second.attr_values += string("}");
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Evaluation of " << it->second.formula << "; result=" << res.value << " quality=" << res.quality << endl;
changed = alarms.update(tmpname, ts, res, it->second.attr_values, it->second.grp2str(), it->second.msg, it->second.formula); //update internal structure and log to db
changed = changed || prev_error;
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": changed=" << (int)changed << endl;
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(attr_name);

Graziano Scalamera
committed
if(!it->second.enabled)
*attr_value = _OOSRV;
else if(it->second.shelved && it->second.silenced > 0)
*attr_value = _SHLVD;
else if((it->second.stat == S_NORMAL) && it->second.ack == ACK)
*attr_value = _NORM;
else if((it->second.stat == S_ALARM) && it->second.ack == NOT_ACK)
*attr_value = _UNACK;
else if((it->second.stat == S_ALARM) && it->second.ack == ACK)
*attr_value = _ACKED;
else if((it->second.stat == S_NORMAL) && it->second.ack == NOT_ACK)
*attr_value = _RTNUN;
Tango::AttrQuality quality = (Tango::AttrQuality)it->second.quality;
ex_reason = it->second.ex_reason; //copying again because updated with formula result res.ex_reason in alarms.update
ex_desc = it->second.ex_desc;
ex_origin = it->second.ex_origin;
alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks
try
{ //DevFailed for push events

Graziano Scalamera
committed
{
timeval now;
gettimeofday(&now, NULL);
push_change_event(attr_name,(Tango::DevEnum *)attr_value,now,quality, 1/*size*/, 0, false);
push_archive_event(attr_name,(Tango::DevEnum *)attr_value,now,quality, 1/*size*/, 0, false);

Graziano Scalamera
committed
}
else
{
Tango::DevErrorList errors(1);
errors.length(1);
errors[0].desc = CORBA::string_dup(ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(ex_reason.c_str());
errors[0].origin = CORBA::string_dup(ex_origin.c_str());
Tango::DevFailed except(errors);
push_change_event(attr_name, &except);
push_archive_event(attr_name, &except);
} catch(Tango::DevFailed & ex)
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << attr_name << " - EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;
}
} catch(std::out_of_range& ex)
{
it->second.to_be_evaluated = true;
ostringstream o;
o << tmpname << ": in formula array index out of range!";
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = string("OUT_OF_RANGE");
it->second.ex_desc = ev_name + ": " + o.str();
it->second.ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks
push_change_event(attr_name, &except);
push_archive_event(attr_name, &except);
} catch(Tango::DevFailed & ex)
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << attr_name << " - EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;
}
} catch(string & ex)
{
it->second.to_be_evaluated = true;
ostringstream o;
o << tmpname << ": in formula err=" << ex;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = string("FORMULA_ERROR");
it->second.ex_desc = ev_name + ": " + o.str();
it->second.ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks
push_change_event(attr_name, &except);
push_archive_event(attr_name, &except);
} catch(Tango::DevFailed & ex)
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << attr_name << " - EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;

Graziano Scalamera
committed
}
}
}
else
{
ostringstream o;
//o << j->first << ": not found formula in alarm table" << ends;
o << (alm_name) << ": not found formula in alarm table";
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
#if 0 //TODO: attribute not existing -> cannot notify error pushing exception
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
string ex_reason = string("NOT_FOUND");
string ex_desc = ev_name + ": " + o.str();
string ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(ex_reason.c_str());
errors[0].origin = CORBA::string_dup(ex_origin.c_str());
Tango::DevFailed except(errors);
//push_change_event(it->second.attr_name, &except);
//push_archive_event(it->second.attr_name, &except);
} catch(Tango::DevFailed & ex)

Graziano Scalamera
committed
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;

Graziano Scalamera
committed
}

Graziano Scalamera
committed
}
//alarms.vlock->readerOut();
return changed;
}

Graziano Scalamera
committed
void AlarmHandler::timer_update()

Graziano Scalamera
committed
{
bool changed=true;

Graziano Scalamera
committed
//DEBUG_STREAM << "AlarmHandler::timer_update(): entering..." << endl;

Graziano Scalamera
committed
try {
changed=alarms.timer_update();
} catch(string & e)
{
ostringstream o;
o << "Error checking time thresholds and updating alarm status=" << e;
WARN_STREAM << "AlarmHandler::timer_update(): " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
/* Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = string("INTERNAL_ERROR");
it->second.ex_desc = o.str();
it->second.ex_origin = string("AlarmHandler::timer_update");
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
push_change_event(it->second.attr_name, &except);
push_archive_event(it->second.attr_name, &except);*/

Graziano Scalamera
committed
}
if(!changed)

Graziano Scalamera
committed
return;
prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway

Graziano Scalamera
committed
try
{
if(ds_num == 0)
{
//attr.set_value_date_quality(ds,0/*gettime()*/,Tango::ATTR_WARNING, ds_num, 0, false);
struct timeval now;
gettimeofday(&now,NULL);
push_change_event("alarm",(char**)ds,now,Tango::ATTR_WARNING, ds_num, 0, false);
}
else

Graziano Scalamera
committed
{

Graziano Scalamera
committed
//attr.set_value(ds, ds_num, 0, false);
push_change_event("alarm",ds, ds_num, 0, false);

Graziano Scalamera
committed
}
push_change_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_change_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_change_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_change_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_change_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_change_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_change_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_change_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_change_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_change_event("alarmAudible",attr_alarmAudible_read);
push_change_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
push_archive_event("alarmNormal",&attr_alarmNormal_read[0], normalAlarms_sz);
push_archive_event("alarmUnacknowledged",&attr_alarmUnacknowledged_read[0], unacknowledgedAlarms_sz);
push_archive_event("alarmAcknowledged",&attr_alarmAcknowledged_read[0], acknowledgedAlarms_sz);
push_archive_event("alarmUnacknowledgedNormal",&attr_alarmUnacknowledgedNormal_read[0], unacknowledgedNormalAlarms_sz);
push_archive_event("alarmShelved",&attr_alarmShelved_read[0], shelvedAlarms_sz);
push_archive_event("alarmOutOfService",&attr_alarmOutOfService_read[0], outOfServiceAlarms_sz);
push_archive_event("alarmSilenced",&attr_alarmSilenced_read[0], silencedAlarms_sz);
push_archive_event("alarmList",&attr_alarmList_read[0], listAlarms_sz);
push_archive_event("alarmFrequency",&attr_alarmFrequency_read[0], listAlarms_sz);
push_archive_event("alarmAudible",attr_alarmAudible_read);
push_archive_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);

Graziano Scalamera
committed
} catch(Tango::DevFailed& e)
{
ostringstream err;
err << "error pushing alarm change event err=" << e.errors[0].desc;
INFO_STREAM << __func__<<": " << err.str() << endl;
}
}
bool AlarmHandler::remove_alarm(string& s) throw(string&)

Graziano Scalamera
committed
{
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": entering alm name=" << s << endl;

Graziano Scalamera
committed
alarms.vlock->writerIn();
alarm_container_t::iterator i = alarms.v_alarm.find(s);
if (i != alarms.v_alarm.end()) {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": found in table alm name=" << s << endl;

Graziano Scalamera
committed
for (set<string>::iterator j = i->second.s_event.begin(); \
j != i->second.s_event.end(); j++) {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": looping event =" << *j << endl;