Newer
Older
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
3027
3028
3029
3030
3031
/*----- 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);
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;
size_t start_pos = 0;
string from("/");
string to("__");
while((start_pos = alm.attr_name.find(from, start_pos)) != std::string::npos)
{
alm.attr_name.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}

Graziano Scalamera
committed
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
//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
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;
}
else
{
ostringstream o;
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

Graziano Scalamera
committed
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.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;
o << e.msg << endl;
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;
//LOOP ALARMS IN WHICH THIS EVENT IS USED
list<string> m_alarm=found_ev->m_alarm.show();
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
if(e.type == TYPE_TANGO_ERR)
it->second.ex_reason = found_ev->ex_reason;
else
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++;
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
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();
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, found->ts);
if(changed)
num_changed++;
j++;
}
if(num_changed==0)
{
prepare_alm_mtx->lock();
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++;
}
alarms.vlock->readerOut();
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);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before lock name=" << alm_name<< " ev=" << ev_name << endl;
alarms.vlock->readerIn();
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": after lock name=" << alm_name<< " ev=" << ev_name << endl;
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;

Graziano Scalamera
committed
/*
* for each event into the per-alarm event list find
* the event table entry and remove this alarm from
* per-event alarm list
*/
vector<event>::iterator k = \
find(events->v_event.begin(), events->v_event.end(), *j);
if (k != events->v_event.end()) {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": found event =" << *j << " in vector events, removing from its alarm list name=" << i->second.name << endl;

Graziano Scalamera
committed
/*
* remove alarm
*/
k->m_alarm.pop(i->second.name);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": after m_alarm.pop" << endl;

Graziano Scalamera
committed
if (k->m_alarm.empty()) {
/*
* no more alarms associated to this event, unsubscribe
* and remove from event table
*/
DEBUG_STREAM << "AlarmHandler::remove_alarm(): removing event '" \

Graziano Scalamera
committed
<< k->name << "' from event table" << endl;
try {
events->stop(k->name);
events->remove(k->name, false);

Graziano Scalamera
committed
} catch (...) {
ostringstream o;
o << "unsubscribe_event() failed for " \
WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl;

Graziano Scalamera
committed
alarms.vlock->writerOut();
throw o.str();
//return false;
}

Graziano Scalamera
committed
}
} else {
/*
* shouldn't happen!!!
*/
ostringstream o;
o << "event '" << *j \
WARN_STREAM << "AlarmHandler::remove_alarm(): " << o.str() << endl;