1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
38 #include <anna/core/oam/Module.hpp>
39 #include <anna/core/functions.hpp>
40 #include <anna/core/oam/Configuration.hpp>
42 #include <anna/core/tracing/Logger.hpp>
43 #include <anna/core/tracing/TraceWriter.hpp>
44 #include <anna/core/tracing/TraceMethod.hpp>
45 #include <anna/core/functions.hpp>
46 #include <anna/xml/xml.hpp>
47 #include <anna/core/oam/CounterManager.hpp>
53 #define UNDEFINED_EVENT_DESCRIPTION "<undefined>"
56 //******************************************************************************
57 //----------------------------------------------------------------------- Module
58 //******************************************************************************
60 //------------------------------------------------------------------------------
61 //----------------------------------------------------------- Module::getScope()
62 //------------------------------------------------------------------------------
63 anna::oam::CounterScope *anna::oam::Module::getScope(const int &id) throw() {
64 scope_iterator it = scope_find(id);
65 return ((it != scope_end()) ? scope(it) : NULL);
68 ////------------------------------------------------------------------------------
69 ////------------------------------------------------------- Module::alarm_remove()
70 ////------------------------------------------------------------------------------
71 //bool anna::oam::Module::alarm_remove(const int &key) throw() {
72 // alarm_iterator it = alarm_find(key);
73 // if (it != alarm_end()) {
74 // a_alarms.erase(key);
81 ////------------------------------------------------------------------------------
82 ////----------------------------------------------------- Module::counter_remove()
83 ////------------------------------------------------------------------------------
84 //bool anna::oam::Module::counter_remove(const int &key) throw() {
85 // counter_iterator it = counter_find(key);
86 // if (it != counter_end()) {
87 // a_counters.erase(key);
98 //------------------------------------------------------------------------------
99 //----------------------------------------------------- Module::enableCounters()
100 //------------------------------------------------------------------------------
101 void anna::oam::Module::enableCounters(void) throw() {
102 a_counters_enabled = true;
103 LOGDEBUG(anna::Logger::debug("Scoped counters ENABLED", ANNA_FILE_LOCATION));
107 //------------------------------------------------------------------------------
108 //---------------------------------------------------- Module::disableCounters()
109 //------------------------------------------------------------------------------
110 void anna::oam::Module::disableCounters(void) throw() {
111 a_counters_enabled = false;
112 LOGDEBUG(anna::Logger::debug("Scoped counters DISABLED", ANNA_FILE_LOCATION));
116 //------------------------------------------------------------------------------
117 //------------------------------------------------------- Module::enableAlarms()
118 //------------------------------------------------------------------------------
119 void anna::oam::Module::enableAlarms(void) throw() {
120 a_alarms_enabled = true;
121 LOGDEBUG(anna::Logger::debug("Scoped alarms ENABLED", ANNA_FILE_LOCATION));
125 //------------------------------------------------------------------------------
126 //------------------------------------------------------ Module::disableAlarms()
127 //------------------------------------------------------------------------------
128 void anna::oam::Module::disableAlarms(void) throw() {
129 a_alarms_enabled = false;
130 LOGDEBUG(anna::Logger::debug("Scoped alarms DISABLED", ANNA_FILE_LOCATION));
134 //------------------------------------------------------------------------------
135 //------------------------------------------------ Module::enableAlarmsPreffix()
136 //------------------------------------------------------------------------------
137 void anna::oam::Module::enableAlarmsPreffix(void) throw() {
138 a_alarms_preffix_enabled = true;
139 LOGDEBUG(anna::Logger::debug("Alarm preffix module components SHOWN", ANNA_FILE_LOCATION));
143 //------------------------------------------------------------------------------
144 //------------------------------------------------- Module::enableAlarmsSuffix()
145 //------------------------------------------------------------------------------
146 void anna::oam::Module::enableAlarmsSuffix(void) throw() {
147 a_alarms_suffix_enabled = true;
148 LOGDEBUG(anna::Logger::debug("Alarm suffix module components SHOWN", ANNA_FILE_LOCATION));
152 //------------------------------------------------------------------------------
153 //----------------------------------------------- Module::disableAlarmsPreffix()
154 //------------------------------------------------------------------------------
155 void anna::oam::Module::disableAlarmsPreffix(void) throw() {
156 a_alarms_preffix_enabled = false;
157 LOGDEBUG(anna::Logger::debug("Alarm preffix module components HIDDEN", ANNA_FILE_LOCATION));
161 //------------------------------------------------------------------------------
162 //------------------------------------------------ Module::disableAlarmsSuffix()
163 //------------------------------------------------------------------------------
164 void anna::oam::Module::disableAlarmsSuffix(void) throw() {
165 a_alarms_suffix_enabled = false;
166 LOGDEBUG(anna::Logger::debug("Alarm suffix module components HIDDEN", ANNA_FILE_LOCATION));
170 //------------------------------------------------------------------------------
171 //--------------------------------- Module::getDefaultInternalAlarmDescription()
172 //------------------------------------------------------------------------------
173 std::string anna::oam::Module::getDefaultInternalAlarmDescription(const int & type) const throw() {
174 return UNDEFINED_EVENT_DESCRIPTION;
178 //------------------------------------------------------------------------------
179 //------------------------------- Module::getDefaultInternalCounterDescription()
180 //------------------------------------------------------------------------------
181 std::string anna::oam::Module::getDefaultInternalCounterDescription(const int & type) const throw() {
182 return UNDEFINED_EVENT_DESCRIPTION;
186 //------------------------------------------------------------------------------
187 //---------------------------------------------- Module::alarmComponentsToText()
188 //------------------------------------------------------------------------------
189 std::string anna::oam::Module::alarmComponentsToText(const std::vector<std::string> & components, const std::string & psL, const std::string & psS, const std::string & psR) const throw() {
190 if(components.size() == 0) return ("");
192 std::vector<std::string>::const_iterator it_min(components.begin());
193 std::vector<std::string>::const_iterator it_max(components.end());
194 std::vector<std::string>::const_iterator it, it_last = it_max - 1;
195 std::string result = psL;
197 for(it = it_min; it != it_last; it++) { result += (*it); result += psS; }
199 result += (*it_last);
205 //------------------------------------------------------------------------------
206 //------------------------------ Module::getAlarmPreffixSuffixAndZoneSeparator()
207 //------------------------------------------------------------------------------
208 void anna::oam::Module::getAlarmPreffixSuffixAndZoneSeparator(std::string & preffix, std::string & suffix, char & zS) const throw() {
209 Configuration &conf = Configuration::instantiate();
210 const std::vector<std::string> * globalPreffixComponents = conf.getAlarmPreffixComponents();
211 const std::vector<std::string> * globalSuffixComponents = conf.getAlarmSuffixComponents();
212 std::vector<std::string> preffixComponents, suffixComponents, compsAux;
214 if(globalPreffixComponents) preffixComponents = *globalPreffixComponents;
216 if(globalSuffixComponents) suffixComponents = *globalSuffixComponents;
218 if(a_alarms_preffix_enabled) {
219 // Read from virtual and append to global configuration ones:
220 readAlarmPreffixComponents(compsAux);
222 if(compsAux.size() != 0) preffixComponents.insert(preffixComponents.begin(), compsAux.begin(), compsAux.end());
225 if(a_alarms_suffix_enabled) {
226 // Read from virtual and append to global configuration ones:
228 readAlarmSuffixComponents(compsAux);
230 if(compsAux.size() != 0) suffixComponents.insert(suffixComponents.begin(), compsAux.begin(), compsAux.end());
233 // Build final preffix and suffix from its components:
234 std::string psL, psS, psR;
235 conf.getAlarmTextDelimiters(zS, psL, psS, psR);
236 preffix = alarmComponentsToText(preffixComponents, psL, psS, psR);
237 suffix = alarmComponentsToText(suffixComponents, psL, psS, psR);
243 //------------------------------------------------------------------------------
244 //--------------------------------------------- Module::initializeCounterScope()
245 //------------------------------------------------------------------------------
246 void anna::oam::Module::initializeCounterScope(const int & scopeId, const std::string & description) throw(anna::RuntimeException) {
247 LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "initializeCounterScope", ANNA_FILE_LOCATION));
250 if(a_counters.size() != 0) // any counter have been registered
251 throw anna::RuntimeException("After use of counter registration can't initialize more scope ids!. Do initializations firstly", ANNA_FILE_LOCATION);
253 // Scope range: 0 - 99
254 if(scopeId < 0 || scopeId >= anna::oam::CounterManager::MaxScope) {
255 std::string msg = "Scope Id must be in range [0 - ";
256 msg += anna::functions::asString(anna::oam::CounterManager::MaxScope - 1); // 99
258 throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
261 // Check module scopes:
262 if(getScope(scopeId)) {
263 std::string msg = "Scope Id '";
264 msg += anna::functions::asString(scopeId);
265 msg += "' has already been registered in this module!";
266 throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
270 bool missingScopeDescription = (description == "");
273 if(missingScopeDescription && a_scopes.size() != 0) {
274 anna::Logger::warning("This is not the first initialized scope. Perhaps you should provide specific description better than general module name ...", ANNA_FILE_LOCATION);
277 const char * c_description = (missingScopeDescription ? getClassName() : description.c_str());
278 a_active_counter_scope = &(anna::oam::CounterManager::instantiate().create(scopeId, c_description, true /* reuses */));
279 a_scopes[scopeId] = a_active_counter_scope;
283 //------------------------------------------------------------------------------
284 //---------------------------------------------- Module::setActiveCounterScope()
285 //------------------------------------------------------------------------------
286 void anna::oam::Module::setActiveCounterScope(const int & scopeId) throw() {
287 anna::oam::CounterScope *scope = getScope(scopeId);
290 anna::Logger::error(anna::functions::asString("Provided scope id '%d' can't be activated, because you must initialize it first", scopeId), ANNA_FILE_LOCATION);
294 a_active_counter_scope = scope;
298 //------------------------------------------------------------------------------
299 //---------------------------------------------------- Module::registerCounter()
300 //------------------------------------------------------------------------------
301 void anna::oam::Module::registerCounter(const int & type, const std::string & description, const int & offset) throw(anna::RuntimeException) {
303 a_handler->registerCounter(this, type, description, offset);
306 if(a_scopes.size() == 0) // at least one scope must be initialized
307 throw anna::RuntimeException("Before counter registration, at least one counter scope must be initialized at oam module", ANNA_FILE_LOCATION);
309 // Check type existence:
310 const_counter_iterator counter_it = counter_find(type);
312 if(counter_it != counter_end()) {
313 std::string msg = "There is a former counter registered with enum value (counter type) = ";
314 msg += anna::functions::asString(type);
315 throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
318 // If description is empty, get the default defined
319 std::string _description = ((description != "") ? description : getDefaultInternalCounterDescription(type));
322 aux.Description = _description;
323 // Register for all initialized scopes:
325 for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
326 int scopeId = (*scope_it).first;
327 anna::oam::CounterScope * counterScope = scope(scope_it);
328 counterScope->create(offset, _description.c_str());
331 std::string msg = "Added counter '";
333 msg += "' over scope '";
334 msg += counterScope->getName();
335 msg += "': ScopeId/Offset [RealCounterId] = ";
336 msg += anna::functions::asString(scopeId); msg += "/";
337 msg += anna::functions::asString(offset); msg += " [";
338 msg += anna::functions::asString((scopeId * anna::oam::CounterScope::MaxCounter) + offset); msg += "]";
339 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
343 a_counters[type] = aux;
348 //------------------------------------------------------------------------------
349 //------------------------------------------------------ Module::registerAlarm()
350 //------------------------------------------------------------------------------
351 void anna::oam::Module::registerAlarm(const int & type, const std::string &description, const int & externalId, const std::string & dynamicVariablesCSL, const int & activationId, const int & cancellationId) throw(anna::RuntimeException) {
353 a_handler->registerAlarm(this, type, description, externalId, dynamicVariablesCSL, activationId, cancellationId);
354 // Check type existence:
355 const_alarm_iterator alarm_it = alarm_find(type);
357 if(alarm_it != alarm_end()) {
358 std::string msg = "There is a former alarm registered with enum value (alarm type) = ";
359 msg += anna::functions::asString(type);
360 throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
363 // If description is empty, get the default defined
364 std::string _description = ((description != "") ? description : getDefaultInternalAlarmDescription(type));
366 aux.ExternalId = externalId;
367 aux.DynamicVariablesCSL = dynamicVariablesCSL;
368 aux.ActivationId = activationId;
369 aux.CancellationId = cancellationId;
370 aux.Description = _description;
371 a_alarms[type] = aux;
374 std::string msg = "Added alarm '";
376 msg += "': externalId[dynamicVariablesCSL]/activationId";
378 if(cancellationId != -1) msg += "/cancellationId";
380 msg += anna::functions::asString(externalId); msg += "[";
381 msg += anna::functions::asString(dynamicVariablesCSL); msg += "]/";
382 msg += anna::functions::asString(activationId);
383 if(cancellationId != -1) {
385 msg += anna::functions::asString(cancellationId);
387 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
392 //------------------------------------------------------------------------------
393 //------------------------------------------------------ Module::activateAlarm()
394 //------------------------------------------------------------------------------
395 void anna::oam::Module::alarmEvent(bool activation, const int & type, va_list argList) const throw() {
396 // Preffix/Suffix and separator:
397 std::string userPreffix, userSuffix; char separator;
398 getAlarmPreffixSuffixAndZoneSeparator(userPreffix, userSuffix, separator);
399 const char *preffix = ((userPreffix != "") ? userPreffix.c_str() : NULL);
400 const char *suffix = ((userSuffix != "") ? userSuffix.c_str() : NULL);
402 va_copy(ap, argList); // http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
403 a_handler->alarmEvent(this, preffix, suffix, separator, activation, type, ap);
408 //------------------------------------------------------------------------------
409 //------------------------------------------------------ Module::activateAlarm()
410 //------------------------------------------------------------------------------
411 void anna::oam::Module::activateAlarm(const int & type, ...) const throw(anna::RuntimeException) {
412 // LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "activateAlarm", ANNA_FILE_LOCATION));
415 if(!a_alarms_enabled) {
418 std::string msg = "Alarm activation ignored over module '";
419 msg += getClassName();
420 msg += "': alarms are disabled";
421 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
428 va_start(argList, type);
429 alarmEvent(true, type, argList);
434 //------------------------------------------------------------------------------
435 //-------------------------------------------------------- Module::cancelAlarm()
436 //------------------------------------------------------------------------------
437 void anna::oam::Module::cancelAlarm(const int & type, ...) const throw(anna::RuntimeException) {
438 // LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "cancelAlarm", ANNA_FILE_LOCATION));
441 if(!a_alarms_enabled) {
444 std::string msg = "Alarm cancellation ignored over module '";
445 msg += getClassName();
446 msg += "': alarms are disabled";
447 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
454 va_start(argList, type);
455 alarmEvent(false, type, argList);
460 //------------------------------------------------------------------------------
461 //-------------------------------------------------------------- Module::count()
462 //------------------------------------------------------------------------------
463 void anna::oam::Module::count(const int & type, const int & amount) throw(anna::RuntimeException) {
464 // LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "count", ANNA_FILE_LOCATION));
467 if(!a_counters_enabled) {
470 std::string msg = "Count operation ignored over module '";
471 msg += getClassName();
472 msg += "': counters are disabled";
473 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
478 a_handler->counterEvent(this, type, amount);
482 //------------------------------------------------------------------------------
483 //------------------------------------------------------ Module::resetCounters()
484 //------------------------------------------------------------------------------
485 int anna::oam::Module::resetCounters(const int & scopeId) throw() {
486 LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "resetCounters", ANNA_FILE_LOCATION));
487 int result = 0; // affected number
489 for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++)
490 result += scope(scope_it)->resetAccValues();
496 //------------------------------------------------------------------------------
497 //----------------------------------------------------------- Module::asString()
498 //------------------------------------------------------------------------------
499 std::string anna::oam::Module::asString(void) const throw() {
501 trace = "Module name: '";
502 trace += getClassName();
504 trace += "\n\nCOUNTERS"; trace += "\n--------";
505 trace += "\nScoped counters "; trace += a_counters_enabled ? "Enabled" : "Disabled";
506 trace += "\nCounter Scopes: "; trace += anna::functions::asString(a_scopes.size());
508 for(const_scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
509 trace += "\n\nCounter Scope:";
510 int scopeId = (*scope_it).first;
511 trace += " Id: "; trace += anna::functions::asString(scopeId);
512 trace += " | Description: '"; trace += scope(scope_it)->getName(); trace += "'";
513 trace += "\nRegistered counters:\n";
514 counter_data_t * ptrCounterData;
516 for(const_counter_iterator cnt_it = counter_begin(); cnt_it != counter_end(); cnt_it++) {
517 ptrCounterData = (counter_data_t *) & ((*cnt_it).second);
519 trace += "\n\tType: "; trace += anna::functions::asString((*cnt_it).first);
520 trace += " | Description: '"; trace += ptrCounterData->Description; trace += "'";
521 int offset = ptrCounterData->Offset;
522 int realId = (1000 * scopeId) + offset;
523 trace += " | ScopeId/Offset: "; trace += anna::functions::asString(scopeId); trace += "/"; trace += anna::functions::asString(offset);
524 trace += " | RealId: "; trace += anna::functions::asString(realId);
525 unsigned long long int accValue = scope(scope_it)->getAccValue(offset);
527 if(accValue != 0ULL) {
528 trace += " | AccumulatedAmount: ";
529 trace += anna::functions::asString("%llu", accValue);
534 trace += "\n\nALARMS"; trace += "\n------";
535 trace += "\nScoped alarms "; trace += a_alarms_enabled ? "Enabled" : "Disabled";
536 trace += "\nPreffix alarm components: "; trace += a_alarms_preffix_enabled ? "Shown" : "Hidden";
537 trace += "\nSuffix alarm components: "; trace += a_alarms_suffix_enabled ? "Shown" : "Hidden";
538 trace += "\nRegistered alarms:\n";
540 for(const_alarm_iterator alrm_it = alarm_begin(); alrm_it != alarm_end(); alrm_it++) {
541 int cancellationId = (*alrm_it).second.CancellationId;
542 bool transferable = (cancellationId != -1);
543 trace += "\n\tType: "; trace += anna::functions::asString((*alrm_it).first);
544 trace += " | Description: '"; trace += (*alrm_it).second.Description;
545 trace += transferable ? "' [transferable alarm]" : "'";
546 trace += " | DatabaseId: "; trace += anna::functions::asString((*alrm_it).second.ExternalId);
547 trace += " | dynamicVariablesCSL: "; trace += (*alrm_it).second.DynamicVariablesCSL;
548 trace += " | ActivationId: "; trace += anna::functions::asString((*alrm_it).second.ActivationId);
550 if(transferable) { trace += " | CancellationId: "; trace += anna::functions::asString(cancellationId); }
558 //------------------------------------------------------------------------------
559 //-------------------------------------------------------------- Module::asXML()
560 //------------------------------------------------------------------------------
561 anna::xml::Node* anna::oam::Module::asXML(anna::xml::Node* parent) const throw() {
562 anna::xml::Node* result = parent->createChild("oam.Module");
563 result->createAttribute("Name", getClassName());
564 result->createAttribute("Counters", a_counters_enabled ? "Enabled" : "Disabled");
565 anna::xml::Node* registeredCounterScopes = result->createChild("RegisteredCounterScopes");
567 for(const_scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
569 anna::xml::Node* scopeNode = registeredCounterScopes->createChild("Scope");
570 int scopeId = (*scope_it).first;
571 scopeNode->createAttribute("Id", anna::functions::asString(scopeId));
572 scopeNode->createAttribute("Description", scope(scope_it)->getName());
574 anna::xml::Node* registeredCounters = scopeNode->createChild("RegisteredCounters");
575 counter_data_t * ptrCounterData;
577 for(const_counter_iterator cnt_it = counter_begin(); cnt_it != counter_end(); cnt_it++) {
578 ptrCounterData = (counter_data_t *) & ((*cnt_it).second);
580 anna::xml::Node* counter = registeredCounters->createChild("Counter");
581 counter->createAttribute("Type", anna::functions::asString((*cnt_it).first));
582 counter->createAttribute("Description", ptrCounterData->Description);
583 int offset = ptrCounterData->Offset;
584 int realId = (1000 * scopeId) + offset;
585 counter->createAttribute("ScopeId", anna::functions::asString(scopeId));
586 counter->createAttribute("Offset", anna::functions::asString(offset));
587 counter->createAttribute("RealId", anna::functions::asString(realId));
588 unsigned long long int accValue = scope(scope_it)->getAccValue(offset);
591 counter->createAttribute("AccumulatedAmount", anna::functions::asString("%llu", accValue));
595 result->createAttribute("Alarms", a_alarms_enabled ? "Enabled" : "Disabled");
596 result->createAttribute("PreffixAlarmComponents", a_alarms_preffix_enabled ? "Shown" : "Hidden");
597 result->createAttribute("SuffixAlarmComponents", a_alarms_suffix_enabled ? "Shown" : "Hidden");
598 anna::xml::Node* registeredAlarms = result->createChild("RegisteredAlarms");
600 for(const_alarm_iterator alrm_it = alarm_begin(); alrm_it != alarm_end(); alrm_it++) {
601 anna::xml::Node* alarm;
602 int cancellationId = (*alrm_it).second.CancellationId;
603 bool transferable = (cancellationId != -1);
604 alarm = registeredAlarms->createChild("Alarm");
605 alarm->createAttribute("Type", anna::functions::asString((*alrm_it).first));
606 std::string desc = (*alrm_it).second.Description; desc += " ["; desc += transferable ? "transferable]" : "non transferable]";
607 alarm->createAttribute("Description", desc);
608 alarm->createAttribute("DatabaseId", anna::functions::asString((*alrm_it).second.ExternalId));
609 alarm->createAttribute("DynamicVariablesCSL", (*alrm_it).second.DynamicVariablesCSL);
610 alarm->createAttribute("ActivationId", anna::functions::asString((*alrm_it).second.ActivationId));
612 if(transferable) alarm->createAttribute("CancellationId", anna::functions::asString(cancellationId));