osaf/libs/common/amf/include/amf_defs.h         |    6 +
 osaf/services/saf/amf/amfnd/Makefile.am         |    1 +
 osaf/services/saf/amf/amfnd/evt.cc              |    7 +
 osaf/services/saf/amf/amfnd/hcdb.cc             |  150 ++++
 osaf/services/saf/amf/amfnd/imm.cc              |  758 ++++++++++++++++++++++++
 osaf/services/saf/amf/amfnd/include/Makefile.am |    1 +
 osaf/services/saf/amf/amfnd/include/avnd.h      |    1 +
 osaf/services/saf/amf/amfnd/include/avnd_evt.h  |    8 +
 osaf/services/saf/amf/amfnd/include/avnd_hc.h   |    1 +
 osaf/services/saf/amf/amfnd/include/avnd_imm.h  |  148 ++++
 osaf/services/saf/amf/amfnd/main.cc             |   10 +-
 11 files changed, 1090 insertions(+), 1 deletions(-)


This first patch adds support for changing attributes in class 
SaAmfHealthcheckType
Updated with review comments.

diff --git a/osaf/libs/common/amf/include/amf_defs.h 
b/osaf/libs/common/amf/include/amf_defs.h
--- a/osaf/libs/common/amf/include/amf_defs.h
+++ b/osaf/libs/common/amf/include/amf_defs.h
@@ -254,6 +254,12 @@ typedef enum
    saAmfHealthcheckMaxDuration_ID = 2,
 } AVSV_AMF_HEALTHCHECK_ATTR_ID; 
 
+/* Attribute ID enum for the SaAmfHealthcheckType class */
+typedef enum
+{
+   saAmfHctDefPeriod_ID = 1,
+   saAmfHctDefMaxDuration_ID = 2,
+} AMF_HEALTHCHECK_TYPE_ATTR_ID; 
 
 #define AVSV_COMMON_SUB_ID_DEFAULT_VAL 1
 #define SA_AMF_PRESENCE_ORPHANED (SA_AMF_PRESENCE_TERMINATION_FAILED+1)
diff --git a/osaf/services/saf/amf/amfnd/Makefile.am 
b/osaf/services/saf/amf/amfnd/Makefile.am
--- a/osaf/services/saf/amf/amfnd/Makefile.am
+++ b/osaf/services/saf/amf/amfnd/Makefile.am
@@ -51,6 +51,7 @@ osafamfnd_SOURCES = \
        err.cc \
        evt.cc \
        hcdb.cc \
+       imm.cc \
        main.cc \
        mbcsv.cc \
        mds.cc \
diff --git a/osaf/services/saf/amf/amfnd/evt.cc 
b/osaf/services/saf/amf/amfnd/evt.cc
--- a/osaf/services/saf/amf/amfnd/evt.cc
+++ b/osaf/services/saf/amf/amfnd/evt.cc
@@ -32,6 +32,7 @@
 */
 
 #include "avnd.h"
+#include "avnd_imm.h"
 
 /****************************************************************************
   Name          : avnd_evt_create
@@ -200,6 +201,7 @@ AVND_EVT *avnd_evt_create(AVND_CB *cb,
 void avnd_evt_destroy(AVND_EVT *evt)
 {
        uint32_t type = 0;
+       AvndImmEvt *imm = 0;
 
        if (!evt)
                return;
@@ -294,6 +296,11 @@ void avnd_evt_destroy(AVND_EVT *evt)
        case AVND_EVT_PID_EXIT:
                break;
 
+       case AVND_EVT_IMM:
+               imm = static_cast<AvndImmEvt*>(evt->info.imm.imm_evt);
+               delete imm;
+               break;
+
        default:
                LOG_NO("%s: unknown event type %u", __FUNCTION__, type);
                break;
diff --git a/osaf/services/saf/amf/amfnd/hcdb.cc 
b/osaf/services/saf/amf/amfnd/hcdb.cc
--- a/osaf/services/saf/amf/amfnd/hcdb.cc
+++ b/osaf/services/saf/amf/amfnd/hcdb.cc
@@ -36,6 +36,7 @@
 #include "avnd.h"
 #include <saImmOm.h>
 #include <immutil.h>
+#include <string>
 
 static NCS_PATRICIA_TREE hctypedb;     /* healthcheck type db */
 
@@ -339,6 +340,93 @@ SaAisErrorT avnd_hctype_config_get(SaImm
        return error;
 }
 
+// Search for a given key and return its value  or empty string if not found. 
+static std::string search_key(const std::string& str, const std::string& key)
+{
+       std::string value;
+
+       std::string::size_type idx1;
+
+       idx1 = str.find(key);
+
+       // if key was found
+       if (idx1 != std::string::npos) {
+               // get value, idx2 points to value
+               idx1 += key.length();
+               std::string part2 = str.substr(idx1);
+
+               idx1 = part2.find(",");
+
+               // get value
+               value = part2.substr(0, idx1);
+       }
+
+       return value;
+}
+
+//
+static void comp_hctype_update_compdb(AVND_CB *cb, AVSV_PARAM_INFO *param)
+{
+       AVND_COMP_HC_REC *comp_hc_rec;
+       AVND_COMP * comp;
+       char *comp_type_name;
+       AVSV_HLT_KEY hlt_chk;
+       AVND_COMP_HC_REC tmp_hc_rec;
+
+       // 1. find component from componentType, 
+       // input example, param->name.value = 
safHealthcheckKey=AmfDemo,safVersion=1,safCompType=AmfDemo1       
+       comp_type_name = strstr((char *) param->name.value, "safVersion");
+       TRACE("comp_type_name: %s", comp_type_name);
+       osafassert(comp_type_name);
+
+       // 2. search each component for a matching compType
+       comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb, (uint8_t *) 
0);
+       while (comp != 0) {
+               if (strncmp((const char*) comp->saAmfCompType.value, 
comp_type_name, comp->saAmfCompType.length) == 0) {
+
+                       // 3. matching compType found, check that component 
does not have a SaAmfHealthcheck rec (specialization)
+                       std::string hlt_chk_key = search_key((const char*) 
param->name.value, "safHealthcheckKey=");
+                       if (hlt_chk_key.empty()) {
+                               LOG_ER("%s: failed to get healthcheckKey from 
%s", __FUNCTION__, param->name.value);
+                               return;
+                       }
+
+                       memset(&hlt_chk, 0, sizeof(AVSV_HLT_KEY));
+                       hlt_chk.comp_name.length = comp->name.length;
+                       memcpy(hlt_chk.comp_name.value, comp->name.value, 
hlt_chk.comp_name.length);
+                       hlt_chk.key_len = hlt_chk_key.size();
+                       memcpy(hlt_chk.name.key, hlt_chk_key.c_str(), 
hlt_chk_key.size());
+                       hlt_chk.name.keyLen = hlt_chk.key_len;
+                       TRACE("comp_name %s key %s keyLen %u", 
hlt_chk.comp_name.value, hlt_chk.name.key, hlt_chk.name.keyLen);
+                       if (avnd_hcdb_rec_get(cb, &hlt_chk) == 0) {
+                               TRACE("comp uses healthcheckType rec");
+                               // 4. found a component that uses the 
healthcheckType record, update the comp_hc_rec
+                               memset(&tmp_hc_rec, '\0', 
sizeof(AVND_COMP_HC_REC));
+                               tmp_hc_rec.key = hlt_chk.name;
+                               tmp_hc_rec.req_hdl = comp->reg_hdl;
+                               TRACE("tmp_hc_rec: key %s req_hdl %llu", 
tmp_hc_rec.key.key, tmp_hc_rec.req_hdl);
+                               if ((comp_hc_rec = 
m_AVND_COMPDB_REC_HC_GET(*comp, tmp_hc_rec)) != 0) {
+                                       TRACE("comp_hc_rec: period %llu max_dur 
%llu", comp_hc_rec->period, comp_hc_rec->max_dur);
+                                       switch (param->attr_id) {
+                                       case saAmfHctDefPeriod_ID:
+                                               comp_hc_rec->period = 
*((SaTimeT *) param->value);
+                                               LOG_NO("%s: saAmfHctDefPeriod 
updated, new value: %" PRIu64, __FUNCTION__, (uint64_t) comp_hc_rec->period);
+                                               break;
+                                       case saAmfHctDefMaxDuration_ID:
+                                               comp_hc_rec->max_dur = 
*((SaTimeT *) param->value);
+                                               LOG_NO("%s: 
saAmfHctDefMaxDuration updated, new value: %" PRIu64, __FUNCTION__, (uint64_t) 
comp_hc_rec->max_dur);
+                                               break;
+                                       default:
+                                               osafassert(0);
+                                       }
+                               }
+                       }
+               }
+               comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb, 
(uint8_t *) & comp->name);
+       }
+}
+
+//
 uint32_t avnd_hc_oper_req(AVND_CB *cb, AVSV_PARAM_INFO *param)
 {
        uint32_t rc = NCSCC_RC_FAILURE;
@@ -401,3 +489,65 @@ done:
        return rc;
 }
 
+uint32_t avnd_hctype_oper_req(AVND_CB *cb, AVSV_PARAM_INFO *param)
+{
+       uint32_t rc = NCSCC_RC_FAILURE;
+
+       TRACE_ENTER2("'%s'", param->name.value);
+       AVND_HCTYPE *hctype = (AVND_HCTYPE *) ncs_patricia_tree_get(&hctypedb, 
(uint8_t *)&param->name);
+
+       switch (param->act) {
+       case AVSV_OBJ_OPR_MOD: {
+               if (!hctype) {
+                       LOG_ER("%s: failed to get %s", __FUNCTION__, 
param->name.value);
+                       goto done;
+               }
+
+               switch (param->attr_id) {
+               case saAmfHctDefPeriod_ID:
+                       osafassert(sizeof(SaTimeT) == param->value_len);
+                       hctype->saAmfHctDefPeriod = *((SaTimeT *)param->value);
+                       comp_hctype_update_compdb(cb, param);
+                       break;
+
+               case saAmfHctDefMaxDuration_ID:
+                       osafassert(sizeof(SaTimeT) == param->value_len);
+                       hctype->saAmfHctDefMaxDuration = *((SaTimeT 
*)param->value);
+                       comp_hctype_update_compdb(cb, param);
+                       break;
+
+               default:
+                       LOG_NO("%s: Unsupported attribute %u", __FUNCTION__, 
param->attr_id);
+                       goto done;
+               }
+               break;
+       }
+
+       case AVSV_OBJ_OPR_DEL: {
+               if (hctype != NULL) {
+                       rc = ncs_patricia_tree_del(&hctypedb, 
&hctype->tree_node);
+                       osafassert(rc == NCSCC_RC_SUCCESS);
+                       LOG_IN("Deleted '%s'", param->name.value);
+               } else {
+                       /* 
+                        ** Normal case that happens if a parent of this HC was
+                        ** the real delete target for the CCB.
+                        */
+                        TRACE("already deleted!");
+               }
+
+               break;
+       }
+       default:
+               LOG_NO("%s: Unsupported action %u", __FUNCTION__, param->act);
+               goto done;
+       }
+
+       rc = NCSCC_RC_SUCCESS;
+
+done:
+       rc = NCSCC_RC_SUCCESS;
+
+       TRACE_LEAVE();
+       return rc;
+}
diff --git a/osaf/services/saf/amf/amfnd/imm.cc 
b/osaf/services/saf/amf/amfnd/imm.cc
new file mode 100644
--- /dev/null
+++ b/osaf/services/saf/amf/amfnd/imm.cc
@@ -0,0 +1,758 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2014 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+/*****************************************************************************
+
+  DESCRIPTION: 
+  
+ ****************************************************************************/
+#include <string>
+#include <cstring>
+#include <algorithm> 
+#include <poll.h>
+#include "avnd_imm.h"
+#include "immutil.h"
+
+extern struct ImmutilWrapperProfile immutilWrapperProfile;
+
+//
+SaVersionT AvndImm::immVersion_ = {'A', 2, 11};
+SaImmOiHandleT AvndImm::immOiHandle_ = 0;
+SaImmOiHandleT AvndImm::immOmHandle_ = 0;
+SaSelectionObjectT AvndImm::imm_sel_obj_ = -1;
+AvndImm::UpdateFn AvndImm::update_callback_[AVSV_SA_AMF_CLASS_MAX] = {0};
+
+// This string array must match the AVND_AMF_CLASS_ID enum
+const char *AvndImm::avnd_class_names_[] = {
+  "SaAmfHealthcheckType"
+};
+
+/**
+ * This method adds IMM modification attribute to attribute vector
+ * 
+ * @param attr
+ */
+void AvndImmEvt::set_mod_attr(const SaImmAttrModificationT_2& attr) {
+  SaImmAttrModificationT_2 *tmp = new SaImmAttrModificationT_2;
+  tmp->modType = attr.modType;
+  AvndImmUtil::copySaImmAttrValuesT(tmp->modAttr, attr.modAttr);
+  attr_.push_back(tmp);
+}
+
+
+/**
+ * Destructor
+ */
+AvndImmEvt::~AvndImmEvt() {
+  std::for_each(attr_.begin(), attr_.end(), AvndImmUtil::remove_attr);
+  attr_.clear();
+}
+
+/**
+ * This function returns a pointer to a new string which is a duplicate of the 
string s.
+ * 
+ * @param s
+ * 
+ * @return pointer to new string
+ */
+char *AvndImmUtil::str_dup(const char *s) {
+  char *c = new char[strlen(s) + 1];
+  std::strcpy(c, s);
+  return c;
+}
+
+/**
+ * This function returns the size of given attribute value type.
+ * 
+ * @param attrValueType
+ * 
+ * @return attrValueType size
+ */
+size_t AvndImmUtil::value_size(SaImmValueTypeT attrValueType) {
+  size_t value_size = 0;
+
+  switch (attrValueType) {
+    case SA_IMM_ATTR_SAINT32T:
+      value_size = sizeof(SaInt32T);
+      break;
+    case SA_IMM_ATTR_SAUINT32T:
+      value_size = sizeof(SaUint32T);
+      break;
+    case SA_IMM_ATTR_SAINT64T:
+      value_size = sizeof(SaInt64T);
+      break;
+    case SA_IMM_ATTR_SAUINT64T:
+      value_size = sizeof(SaUint64T);
+      break;
+    case SA_IMM_ATTR_SATIMET:
+      value_size = sizeof(SaTimeT);
+      break;
+    case SA_IMM_ATTR_SANAMET:
+      value_size = sizeof(SaNameT);
+      break;
+    case SA_IMM_ATTR_SAFLOATT:
+      value_size = sizeof(SaFloatT);
+      break;
+    case SA_IMM_ATTR_SADOUBLET:
+      value_size = sizeof(SaDoubleT);
+      break;
+    case SA_IMM_ATTR_SASTRINGT:
+      value_size = sizeof(SaStringT);
+      break;
+    case SA_IMM_ATTR_SAANYT:
+      osafassert(0);
+      break;
+  }
+
+  return value_size;
+}
+
+/**
+ * This function returns class enum corresponding to object name.
+ * 
+ * @param obj_name
+ * @param class_type
+ * 
+ * @return AVSV_AMF_CLASS_ID
+ */
+AVSV_AMF_CLASS_ID AvndImmUtil::object_name_to_class_type(const SaNameT 
*obj_name) {
+  AVSV_AMF_CLASS_ID class_type = AVSV_SA_AMF_CLASS_INVALID;
+
+  /* Cluster and Node Class Related */
+  if (strncmp((char *)&obj_name->value, "safAmfCluster=", 14) == 0) {
+    class_type = AVSV_SA_AMF_CLUSTER;
+  } else if (strncmp((char *)&obj_name->value, "safAmfNode=", 11) == 0) {
+    class_type = AVSV_SA_AMF_NODE;
+  } else if (strncmp((char *)&obj_name->value, "safAmfNodeGroup=", 16) == 0) {
+    class_type = AVSV_SA_AMF_NODE_GROUP;
+  } else if (strncmp((char *)&obj_name->value, "safInstalledSwBundle=", 21) == 
0) {
+    class_type = AVSV_SA_AMF_NODE_SW_BUNDLE;
+  }
+
+  /* Application Class Related */
+  else if (strncmp((char *)&obj_name->value, "safApp=", 7) == 0) {
+    class_type = AVSV_SA_AMF_APP;
+  } else if (strncmp((char *)&obj_name->value, "safAppType=", 11) == 0) {
+    class_type = AVSV_SA_AMF_APP_BASE_TYPE;
+  }
+
+  /* Service Group Class Related */
+  else if (strncmp((char *)&obj_name->value, "safSg=", 6) == 0) {
+    class_type = AVSV_SA_AMF_SG;
+  } else if (strncmp((char *)&obj_name->value, "safSgType=", 10) == 0) {
+    class_type = AVSV_SA_AMF_SG_BASE_TYPE;
+  }
+
+  /* Service Unit Class Related */
+  else if (strncmp((char *)&obj_name->value, "safSu=", 6) == 0) {
+    class_type = AVSV_SA_AMF_SU;
+  } else if (strncmp((char *)&obj_name->value, "safSuType=", 10) == 0) {
+    class_type = AVSV_SA_AMF_SU_BASE_TYPE;
+  } else if (strncmp((char *)&obj_name->value, "safMemberCompType=", 18) == 0) 
{
+    class_type = AVSV_SA_AMF_SUT_COMP_TYPE;
+  }
+
+  /* Service Instance Class Related */
+  else if (strncmp((char *)&obj_name->value, "safSi=", 6) == 0) {
+    class_type = AVSV_SA_AMF_SI;
+  } else if (strncmp((char *)&obj_name->value, "safSvcType=", 11) == 0) {
+    class_type = AVSV_SA_AMF_SVC_BASE_TYPE;
+  } else if (strncmp((char *)&obj_name->value, "safDepend=", 10) == 0) {
+    class_type = AVSV_SA_AMF_SI_DEPENDENCY;
+  } else if (strncmp((char *)&obj_name->value, "safRankedSu=", 12) == 0) {
+    class_type = AVSV_SA_AMF_SI_RANKED_SU;
+  } else if (strncmp((char *)&obj_name->value, "safSISU=", 8) == 0) {
+    class_type = AVSV_SA_AMF_SI_ASSIGNMENT;
+  } else if (strncmp((char *)&obj_name->value, "safMemberCSType=", 16) == 0) {
+    class_type = AVSV_SA_AMF_SVC_TYPE_CS_TYPES;
+  }
+
+  /* Component Service Instance Class Related */
+  else if (strncmp((char *)&obj_name->value, "safCsi=", 7) == 0) {
+    class_type = AVSV_SA_AMF_CSI;
+  } else if (strncmp((char *)&obj_name->value, "safCSType=", 10) == 0) {
+    class_type = AVSV_SA_AMF_CS_BASE_TYPE;
+  } else if (strncmp((char *)&obj_name->value, "safCsiAttr=", 11) == 0) {
+    class_type = AVSV_SA_AMF_CSI_ATTRIBUTE;
+  } else if (strncmp((char *)&obj_name->value, "safCSIComp=", 11) == 0) {
+    class_type = AVSV_SA_AMF_CSI_ASSIGNMENT;
+  }
+
+  /* Component and component types Related */
+  else if (strncmp((char *)&obj_name->value, "safCompType=", 12) == 0) {
+    class_type = AVSV_SA_AMF_COMP_BASE_TYPE;
+  } else if (strncmp((char *)&obj_name->value, "safSupportedCsType=", 19) == 
0) {
+    if (strstr((char *)&obj_name->value, "safCompType=") != 0) {
+      class_type = AVSV_SA_AMF_CT_CS_TYPE;
+    } else if (strstr((char *)&obj_name->value, "safComp=") != 0) {
+      class_type = AVSV_SA_AMF_COMP_CS_TYPE;
+    }
+  } else if (strncmp((char *)&obj_name->value, "safComp=", 8) == 0) {
+    class_type = AVSV_SA_AMF_COMP;
+  }
+
+  /* Global Component Attributes and Health Check Related */
+  else if (strncmp((char *)&obj_name->value, "safRdn=", 7) == 0) {
+    class_type = AVSV_SA_AMF_COMP_GLOBAL_ATTR;
+  } else if (strncmp((char *)&obj_name->value, "safHealthcheckKey=", 18) == 0) 
{
+    if (strstr((char *)&obj_name->value, "safVersion=") != 0) {
+      class_type = AVSV_SA_AMF_HEALTH_CHECK_TYPE;
+    } else if (strstr((char *)&obj_name->value, "safComp=") != 0) {
+      class_type = AVSV_SA_AMF_HEALTH_CHECK;
+    }
+  }
+
+  /* Common Version Related */
+  else if (strncmp((char *)&obj_name->value, "safVersion=", 11) == 0) {
+    if (strstr((char *)&obj_name->value, "safAppType=") != 0) {
+      class_type = AVSV_SA_AMF_APP_TYPE;
+    } else if (strstr((char *)&obj_name->value, "safSgType=") != 0) {
+      class_type = AVSV_SA_AMF_SG_TYPE;
+    } else if (strstr((char *)&obj_name->value, "safSuType=") != 0) {
+      class_type = AVSV_SA_AMF_SU_TYPE;
+    } else if (strstr((char *)&obj_name->value, "safSvcType=") != 0) {
+      class_type = AVSV_SA_AMF_SVC_TYPE;
+    } else if (strstr((char *)&obj_name->value, "safCSType=") != 0) {
+      class_type = AVSV_SA_AMF_CS_TYPE;
+    } else if (strstr((char *)&obj_name->value, "safCompType=") != 0) {
+      class_type = AVSV_SA_AMF_COMP_TYPE;
+    }
+  }
+
+  return class_type;
+}
+
+/**
+ * Delete attribute structures.
+ * 
+ * @param attr
+ */
+void AvndImmUtil::remove_attr(SaImmAttrModificationT_2* attr) {
+  AvndImmUtil::deleteSaImmAttrValuesT(attr->modAttr);
+  delete attr;
+}
+
+/**
+ * Delete attribute values.
+ * 
+ * @param reference to attrValue
+ */
+void AvndImmUtil::deleteSaImmAttrValuesT(SaImmAttrValuesT_2& attr_value) {
+  unsigned int i;
+
+  if (attr_value.attrValueType == SA_IMM_ATTR_SASTRINGT) {
+    for (i = 0; i < attr_value.attrValuesNumber; i++) {
+      char *p = *((char**) attr_value.attrValues[i]);
+      delete [] p;
+    }
+  }
+
+  delete [] attr_value.attrName;
+  delete [] static_cast<char*> (attr_value.attrValues[0]); // free blob shared 
by all values
+  delete [] attr_value.attrValues;
+
+}
+
+/**
+ * Copy IMM attr values,
+ * 
+ * @param to
+ * @param from
+ */
+void AvndImmUtil::copySaImmAttrValuesT(SaImmAttrValuesT_2& to, const 
SaImmAttrValuesT_2& from) {
+  size_t val_size = 0;
+  unsigned int i;
+  unsigned int value_count = from.attrValuesNumber;
+  char *databuffer;
+  
+  to.attrName = str_dup(from.attrName);
+
+  to.attrValuesNumber = value_count;
+  to.attrValueType = from.attrValueType;
+  if (value_count == 0)
+    return; /* (just in case...) */
+
+  to.attrValues = new SaImmAttrValueT[value_count];
+
+  val_size = value_size(from.attrValueType);
+
+  // alloc blob shared by all values
+  databuffer = new char[value_count * val_size];
+
+  for (i = 0; i < value_count; i++) {
+    to.attrValues[i] = databuffer;
+    if (from.attrValueType == SA_IMM_ATTR_SASTRINGT) {
+      char *cporig = *((char **) from.attrValues[i]);
+      char **cpp = (char **) databuffer;
+      *cpp = str_dup(cporig);
+    } else {
+      memcpy(databuffer, from.attrValues[i], val_size);
+    }
+    databuffer += val_size;
+  }
+}
+
+/**
+ * Function called for not implemented callback types.
+ * 
+ * @param object_name
+ * @param imm_attr
+ * 
+ * @return   NCSCC_RC_FAILURE;
+ */
+uint32_t AvndImm::not_yet_implemented(const std::string& object_name, const 
SaImmAttrModificationT_2* imm_attr) {
+  LOG_WA("Not yet implemented");       
+  return NCSCC_RC_FAILURE;
+}
+
+/**
+ * Function called for updating health check type.
+ * 
+ * @param object_name
+ * @param imm_attr
+ * 
+ * @return   NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE;
+ */
+uint32_t AvndImm::update_health_check_type(const std::string& object_name, 
const SaImmAttrModificationT_2* imm_attr) {
+  uint32_t rc = NCSCC_RC_FAILURE;
+  AVND_CB *cb = avnd_cb;
+       
+  AVSV_PARAM_INFO param;
+  memset(&param, 0, sizeof(param));
+  param.class_id = AVSV_SA_AMF_HEALTH_CHECK_TYPE;
+
+  std::string attr_name = imm_attr->modAttr.attrName;
+
+  strncpy((char*) param.name.value, object_name.c_str(), object_name.size());
+  param.name.length = object_name.size();
+
+  if (attr_name == "saAmfHctDefPeriod") {
+    param.attr_id = saAmfHctDefPeriod_ID;
+  } else if (attr_name == "saAmfHctDefMaxDuration") {
+    param.attr_id = saAmfHctDefMaxDuration_ID;
+  } else {
+    LOG_WA("Unknown attribute name %s", attr_name.c_str());
+    rc = NCSCC_RC_FAILURE;
+    goto done;
+  }
+
+  if (imm_attr->modType == SA_IMM_ATTR_VALUES_REPLACE) {
+    param.act = AVSV_OBJ_OPR_MOD;
+  } else if (imm_attr->modType == SA_IMM_ATTR_VALUES_DELETE) {
+    param.act = AVSV_OBJ_OPR_DEL;
+  } else {
+    LOG_WA("Unknown modificaton type %d", imm_attr->modType);
+    rc = NCSCC_RC_FAILURE;
+    goto done;
+  }
+
+  param.value_len = AvndImmUtil::value_size(imm_attr->modAttr.attrValueType);
+  memcpy(param.value, *imm_attr->modAttr.attrValues, param.value_len);
+
+  rc = avnd_hctype_oper_req(cb, &param);
+       
+done:
+  return rc;
+}
+
+/**
+ * IMM event handle, dispatch callback function for each changed attribute in 
the current event.
+ * 
+ * @param cb
+ * @param evt
+ * 
+ * @return NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE
+ */
+uint32_t avnd_evt_imm_evh(AVND_CB *cb, AVND_EVT *evt) {
+  AVSV_AMF_CLASS_ID type;
+  uint32_t rc = NCSCC_RC_FAILURE;
+       
+  TRACE_ENTER();
+               
+  AvndImmEvt *imm_evt = (AvndImmEvt*) evt->info.imm.imm_evt;
+
+  // TODO(uabhano) change object_name_to_class_type argument to std::string, 
then the SaNameT code below can be removed
+  SaNameT obj_name;
+  obj_name.length = imm_evt->get_object_name().size();
+  memcpy((char*)obj_name.value, imm_evt->get_object_name().c_str(), 
obj_name.length);
+  type = AvndImmUtil::object_name_to_class_type(&obj_name);
+       
+  for (std::vector<SaImmAttrModificationT_2*>::const_iterator it = 
imm_evt->begin(); it != imm_evt->end(); ++it) {
+    const SaImmAttrModificationT_2 *imm_attr = *it;
+    rc = AvndImm::update_callback_[type](imm_evt->get_object_name(), imm_attr);
+  }
+
+  TRACE_LEAVE();
+  return rc;
+}
+
+/**
+ * Handle imm apply, create and send an AvndImmEvt object to the avnd main 
thread.
+ *
+ * @param immoi_handle
+ * @param ccb_id
+  */
+void AvndImm::ccb_apply_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id) {
+  AVND_EVT_TYPE type = AVND_EVT_IMM;
+
+  AVND_EVT *evt = 0;
+  const SaImmAttrModificationT_2 *mod;
+  int i = 0;
+  CcbUtilCcbData_t *ccb_util_ccb_data;
+  CcbUtilOperationData_t *opdata = NULL;
+  AvndImmEvt *imm_evt;
+  uint32_t rc = NCSCC_RC_SUCCESS;
+  AVND_CB *cb = avnd_cb;
+
+  TRACE_ENTER2("CCB ID %llu", ccb_id);
+
+  while ((opdata = ccbutil_getNextCcbOp(ccb_id, opdata)) != NULL) {
+    imm_evt = new AvndImmEvt(opdata->objectName);
+    while ((mod = opdata->param.modify.attrMods[i++]) != NULL) {
+      imm_evt->set_mod_attr(*mod);
+    }
+
+    i = 0;
+
+    /* create and send an event */
+
+    evt = new AVND_EVT();
+
+    evt->type = type;
+    evt->priority = NCS_IPC_PRIORITY_NORMAL;
+    evt->info.imm.imm_evt = imm_evt;
+
+    rc = m_NCS_IPC_SEND(&cb->mbx, evt, evt->priority);
+    if (rc != NCSCC_RC_SUCCESS) {
+      LOG_CR("AvND send event to mailbox failed, type = %u", evt->type);
+    }
+  }
+
+  /* Return CCB container memory */
+  ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
+  osafassert(ccb_util_ccb_data);
+  ccbutil_deleteCcbData(ccb_util_ccb_data);
+
+  TRACE_LEAVE();
+}
+
+/**
+ * IMM modify callback, memorize the request.
+ * 
+ * @param immoi_handle
+ * @param ccb_id
+ * @param object_name
+ * @param attr_mods
+ * 
+ * @return SA_AIS_OK or or SA_AIS_ERR_xx
+ */
+SaAisErrorT AvndImm::ccb_object_modify_cb(SaImmOiHandleT immoi_handle,
+       SaImmOiCcbIdT ccb_id, const SaNameT *object_name,
+       const SaImmAttrModificationT_2 **attr_mods) {
+  SaAisErrorT rc = SA_AIS_OK;
+  struct CcbUtilCcbData *ccb_util_ccb_data;
+
+  TRACE_ENTER2("CCB ID %llu, %s", ccb_id, object_name->value);
+
+  if ((ccb_util_ccb_data = ccbutil_getCcbData(ccb_id)) != NULL) {
+    /* "memorize the request" */
+    if (ccbutil_ccbAddModifyOperation(ccb_util_ccb_data, object_name, 
attr_mods) != 0) {
+      LOG_ER("Failed '%s'", object_name->value);
+      rc = SA_AIS_ERR_BAD_OPERATION;
+    }
+  } else {
+    LOG_ER("Failed to get CCB object for %llu", ccb_id);
+    rc = SA_AIS_ERR_NO_MEMORY;
+  }
+
+  TRACE_LEAVE();
+
+  return rc;
+}
+
+/**
+ * IMM ccb abort callback.
+ *
+ * @param immoi_handle
+ * @param ccb_id
+ */
+void AvndImm::ccb_abort_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id) {
+  TRACE_ENTER();
+  
+  CcbUtilCcbData_t *ccb_util_ccb_data;
+  
+  /* Return CCB container memory */
+  ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
+  osafassert(ccb_util_ccb_data);
+  ccbutil_deleteCcbData(ccb_util_ccb_data);
+  
+  TRACE_LEAVE();
+}
+
+/**
+ * IMM ccb object delete callback.
+ * 
+ * @param immoi_handle
+ * @param ccb_id,
+ * @param object_name
+  * 
+ * @return SA_AIS_OK
+ */
+SaAisErrorT AvndImm::ccb_object_delete_cb(SaImmOiHandleT immoi_handle,
+       SaImmOiCcbIdT ccb_id, const SaNameT *object_name) {
+
+  TRACE_ENTER();
+  TRACE_LEAVE();
+  
+  return SA_AIS_OK;
+}
+
+/**
+ * IMM ccb completed callback.
+ * 
+ * @param immoi_handle
+ * @param ccb_id,
+   * 
+ * @return SA_AIS_OK
+ */
+SaAisErrorT AvndImm::ccb_completed_cb(SaImmOiHandleT immoi_handle,
+       SaImmOiCcbIdT ccb_id) {
+ 
+  TRACE_ENTER();
+  TRACE_LEAVE();
+
+  return SA_AIS_OK;
+}
+
+/**
+ * IMM ccb object create callback.
+ * 
+ * @param immoi_handle
+ * @param ccb_id
+ * @param class_name
+ * @param parent_name
+ * @param attr
+ * 
+ * @return SA_AIS_OK
+ */
+SaAisErrorT AvndImm::ccb_object_create_cb(SaImmOiHandleT immoi_handle,
+       SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
+       const SaNameT *parent_name, const SaImmAttrValuesT_2 **attr) {
+       
+  TRACE_ENTER();
+  TRACE_LEAVE();
+
+  return SA_AIS_OK;
+}
+
+const SaImmOiCallbacksT_2 AvndImm::avnd_callbacks_ = {
+  .saImmOiAdminOperationCallback = NULL,
+  .saImmOiCcbAbortCallback = ccb_abort_cb,
+  .saImmOiCcbApplyCallback = ccb_apply_cb,
+  .saImmOiCcbCompletedCallback = ccb_completed_cb,
+  .saImmOiCcbObjectCreateCallback = ccb_object_create_cb,
+  .saImmOiCcbObjectDeleteCallback = ccb_object_delete_cb,
+  .saImmOiCcbObjectModifyCallback = ccb_object_modify_cb,
+  .saImmOiRtAttrUpdateCallback = NULL
+};
+
+/**
+ * Set IMM applier.
+ * 
+ * @return SA_AIS_OK or or SA_AIS_ERR_xx
+ */
+SaAisErrorT AvndImm::imm_applier_set() {
+  SaAisErrorT rc = SA_AIS_OK;
+  uint32_t i;
+  std::string applier_name = "@safAmfNodeDirector_";
+
+  TRACE_ENTER();
+
+  char hostname[_POSIX_HOST_NAME_MAX];
+  if (gethostname(hostname, _POSIX_HOST_NAME_MAX) == -1) {
+    LOG_ER("gethostname failed: %s\n", strerror(errno));
+
+    /* use the node id of the node on which the AVD is running instead. */
+    SaClmNodeIdT node_id_avnd = m_NCS_GET_NODE_ID;
+    snprintf(hostname, _POSIX_HOST_NAME_MAX, "%x", node_id_avnd);
+  }
+
+  applier_name += hostname;
+
+  LOG_NO("IMM applier name: %s", applier_name.c_str());
+
+  //
+  if ((rc = immutil_saImmOiImplementerSet(immOiHandle_, (char*) 
applier_name.c_str())) != SA_AIS_OK) {
+    LOG_ER("saImmOiImplementerSet failed %u", rc);
+    return rc;
+  }
+
+  //
+  for (i = 0; i < AVND_SA_AMF_CLASS_MAX; i++) {
+    if ((rc = immutil_saImmOiClassImplementerSet(immOiHandle_, 
avnd_class_names_[i])) != SA_AIS_OK) {
+      LOG_ER("Impl Set Failed for %s, returned %d", avnd_class_names_[i], rc);
+      break;
+    }
+  }
+
+  TRACE_LEAVE();
+
+  return rc;
+}
+
+/**
+ * Initialize IMM.
+ * 
+ * @return SA_AIS_OK or or SA_AIS_ERR_xx
+ */
+SaAisErrorT AvndImm::imm_init() {
+  SaAisErrorT rc = SA_AIS_OK ;
+
+  TRACE_ENTER();
+
+  for (int i = 0; i < AVSV_SA_AMF_CLASS_MAX; ++i) {
+    update_callback_[i] = not_yet_implemented;
+  }
+       
+  update_callback_[AVSV_SA_AMF_HEALTH_CHECK_TYPE] = update_health_check_type;
+       
+  /* Setup immutils profile once and for all */
+  immutilWrapperProfile.errorsAreFatal = false;
+  immutilWrapperProfile.retryInterval = 1000;
+  immutilWrapperProfile.nTries = 180;
+
+  if ((rc = immutil_saImmOiInitialize_2(&immOiHandle_, &avnd_callbacks_, 
&immVersion_)) != SA_AIS_OK) {
+    LOG_ER("saImmOiInitialize failed %u", rc);
+    goto done;
+  }
+
+  if ((rc = immutil_saImmOmInitialize(&immOmHandle_, NULL, &immVersion_)) != 
SA_AIS_OK) {
+    LOG_ER("saImmOmInitialize failed %u", rc);
+    goto done;
+  }
+
+  if ((rc = immutil_saImmOiSelectionObjectGet(immOiHandle_, &imm_sel_obj_)) != 
SA_AIS_OK) {
+    LOG_ER("saImmOiSelectionObjectGet failed %u", rc);
+    goto done;
+  }
+
+  TRACE("Successfully initialized IMM");
+
+done:
+  TRACE_LEAVE();
+
+  return rc;
+}
+
+/**
+ * IMM thread main function, waits for IMM events and dispatch callback 
functions.
+ */
+void AvndImm::imm_main() {
+  SaAisErrorT rc = SA_AIS_OK;
+
+  enum {
+    FD_IMM = 0
+  };
+
+  static nfds_t nfds = FD_IMM + 1;
+  int polltmo = -1;
+  static struct pollfd fds[FD_IMM + 1];
+
+  TRACE_ENTER();
+
+  fds[FD_IMM].fd = imm_sel_obj_;
+  fds[FD_IMM].events = POLLIN;
+  nfds = FD_IMM + 1;
+
+  while (true) {
+    int pollretval = poll(fds, nfds, polltmo);
+
+    if (pollretval == -1) {
+      if (errno == EINTR)
+        continue;
+
+      LOG_ER("main: poll FAILED - %s", strerror(errno));
+      break;
+    }
+
+    if (immOiHandle_ && fds[FD_IMM].revents & POLLIN) {
+      TRACE("IMM event rec");
+      rc = saImmOiDispatch(immOiHandle_, SA_DISPATCH_ALL);
+      if (rc != SA_AIS_OK) {
+        LOG_ER("saImmOiDispatch failed: %d", rc);
+
+      }
+    }
+  }
+
+  TRACE_LEAVE();
+}
+
+/**
+ * IMM thread start function. Init IMM and set as applier.
+ * 
+ * @return 0
+ */
+void *AvndImm::imm_start(void *) {
+  SaAisErrorT rc = SA_AIS_OK;
+
+  TRACE_ENTER();
+
+  if ((rc = imm_init()) != SA_AIS_OK) {
+    LOG_ER("avnd_imm_init FAILED");
+    goto done;  
+  }
+
+  if ((rc = imm_applier_set()) != SA_AIS_OK) {
+    LOG_ER("avnd_imm_applier set FAILED");
+    goto done;  
+  }
+
+  imm_main();
+
+done:
+           
+  return 0;
+}
+
+/**
+ * Create IMM thread for applier functionality. 
+ * 
+ * @return NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE
+ */
+uint32_t avnd_create_imm_thread() {
+  uint32_t rc = NCSCC_RC_SUCCESS;
+  pthread_t thread;
+  pthread_attr_t attr;
+
+  TRACE_ENTER();
+
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+  if (pthread_create(&thread, &attr, AvndImm::imm_start, 0) != 0) {
+    LOG_ER("pthread_create FAILED: %s", strerror(errno));
+    rc = NCSCC_RC_FAILURE;
+  }
+
+  pthread_attr_destroy(&attr);
+
+  TRACE_LEAVE();
+
+  return rc;
+}
+
diff --git a/osaf/services/saf/amf/amfnd/include/Makefile.am 
b/osaf/services/saf/amf/amfnd/include/Makefile.am
--- a/osaf/services/saf/amf/amfnd/include/Makefile.am
+++ b/osaf/services/saf/amf/amfnd/include/Makefile.am
@@ -29,6 +29,7 @@ noinst_HEADERS = \
    avnd_evt.h \
    avnd.h \
    avnd_hc.h \
+   avnd_imm.h \
    avnd_mds.h \
    avnd_mon.h \
    avnd_pg.h \
diff --git a/osaf/services/saf/amf/amfnd/include/avnd.h 
b/osaf/services/saf/amf/amfnd/include/avnd.h
--- a/osaf/services/saf/amf/amfnd/include/avnd.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd.h
@@ -34,6 +34,7 @@
 #define AVND_H
 
 #include <saImmOm.h>
+#include <saImmOi.h>
 
 #include "amf.h"
 #include "ncs_main_papi.h"
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_evt.h 
b/osaf/services/saf/amf/amfnd/include/avnd_evt.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_evt.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_evt.h
@@ -110,6 +110,8 @@ typedef enum avnd_evt_type {
        AVND_EVT_PID_EXIT,
        AVND_EVT_TMR_QSCING_CMPL,
 
+       AVND_EVT_IMM,
+
        AVND_EVT_MAX
 } AVND_EVT_TYPE;
 
@@ -155,6 +157,11 @@ typedef struct avnd_pm_mon_evt {
        AVND_COMP_PM_REC *pm_rec;
 } AVND_PM_MON_EVT;
 
+/* imm event definition */
+typedef struct avnd_imm_evt {
+       void *imm_evt; /* AvndImmEvt ptr */
+} AVND_IMM_EVT;
+
 /* AVND top-level event structure */
 typedef struct avnd_evt_tag {
        struct avnd_evt_tag *next;
@@ -173,6 +180,7 @@ typedef struct avnd_evt_tag {
                AVND_CLC_EVT clc;
                AVND_COMP_FSM_EVT comp_fsm;
                AVND_PM_MON_EVT pm_evt;
+               AVND_IMM_EVT imm;
        } info;
 
 } AVND_EVT;
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_hc.h 
b/osaf/services/saf/amf/amfnd/include/avnd_hc.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_hc.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_hc.h
@@ -59,5 +59,6 @@ extern SaAisErrorT avnd_hc_config_get(st
 extern SaAisErrorT avnd_hctype_config_get(SaImmHandleT immOmHandle, const 
SaNameT *comptype_dn);
 extern AVND_HCTYPE *avnd_hctypedb_rec_get(const SaNameT *comp_type_dn, const 
SaAmfHealthcheckKeyT *key);
 extern uint32_t avnd_hc_oper_req(struct avnd_cb_tag *, AVSV_PARAM_INFO *param);
+extern uint32_t avnd_hctype_oper_req(struct avnd_cb_tag *, AVSV_PARAM_INFO 
*param);
 
 #endif   /* !AVND_HC_H */
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_imm.h 
b/osaf/services/saf/amf/amfnd/include/avnd_imm.h
new file mode 100644
--- /dev/null
+++ b/osaf/services/saf/amf/amfnd/include/avnd_imm.h
@@ -0,0 +1,148 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2014 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+/*****************************************************************************
+  DESCRIPTION:
+ 
+  Classes used for implementing AMF node director as an IMM applier. 
+    
+ ******************************************************************************
+ */
+
+#ifndef AVND_IMM_H
+#define        AVND_IMM_H
+
+#ifdef __cplusplus
+
+#include <vector>
+#include <string>
+#include "avnd.h"
+
+//
+typedef enum {
+  AVND_SA_AMF_HEALTH_CHECK_TYPE = 0,
+  AVND_SA_AMF_CLASS_MAX
+} AVND_AMF_CLASS_ID;
+
+//--------------------------------------------------------------------------
+// < \ingroup avndImm
+//
+// This class is used as a container for one IMM modify callback.
+// >
+//--------------------------------------------------------------------------
+class AvndImmEvt {
+public:
+  //
+  explicit AvndImmEvt(const SaNameT& obj_name) : object_name_((const char*) 
obj_name.value, obj_name.length) {}
+    
+  //
+  ~AvndImmEvt();
+
+  //  
+  std::string get_object_name() {return object_name_;}
+    
+  //
+  void set_mod_attr(const SaImmAttrModificationT_2& attr);
+
+  //
+  typedef typename std::vector<SaImmAttrModificationT_2*>::const_iterator 
const_iterator;
+  const_iterator begin() const {return attr_.begin();}
+  const_iterator end() const {return attr_.end();}
+ 
+private:
+  //
+  AvndImmEvt(const AvndImmEvt&);
+  void operator=(const AvndImmEvt&);
+  
+  std::string object_name_;
+  
+  std::vector<SaImmAttrModificationT_2*> attr_;
+};
+
+//--------------------------------------------------------------------------
+// < \ingroup avndImm
+//
+// This class contains utility functions for IMM.
+// >
+//--------------------------------------------------------------------------
+class AvndImmUtil {
+public:
+  //
+  static void deleteSaImmAttrValuesT(SaImmAttrValuesT_2& attr_value);
+  static void copySaImmAttrValuesT(SaImmAttrValuesT_2& to, const 
SaImmAttrValuesT_2& from);
+  static char *str_dup(const char *str);
+  static size_t value_size(SaImmValueTypeT attrValueType);
+  static AVSV_AMF_CLASS_ID object_name_to_class_type(const SaNameT* obj_name);
+  static void remove_attr(SaImmAttrModificationT_2* attr);
+private:
+  AvndImmUtil();
+  AvndImmUtil(const AvndImmUtil&);
+  void operator=(const AvndImmUtil&);
+};
+
+//--------------------------------------------------------------------------
+// < \ingroup avndImm
+//
+// This class contains IMM callback, init and set functions.
+// >
+//--------------------------------------------------------------------------
+class AvndImm {
+ public:
+  //
+  typedef uint32_t (*UpdateFn) (const std::string& dn, const 
SaImmAttrModificationT_2* attr);
+
+  //
+  static void ccb_abort_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id);
+  static SaAisErrorT ccb_object_delete_cb(SaImmOiHandleT immoi_handle, 
SaImmOiCcbIdT ccb_id, const SaNameT *object_name);
+  static void ccb_apply_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT ccb_id);
+  static SaAisErrorT ccb_completed_cb(SaImmOiHandleT immoi_handle, 
SaImmOiCcbIdT ccb_id);
+  static SaAisErrorT ccb_object_create_cb(SaImmOiHandleT immoi_handle, 
SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
+                                          const SaNameT *parent_name, const 
SaImmAttrValuesT_2 **attr);
+  static SaAisErrorT ccb_object_modify_cb(SaImmOiHandleT immoi_handle, 
SaImmOiCcbIdT ccb_id, const SaNameT *object_name, const 
SaImmAttrModificationT_2 **attr_mods);
+  static void *imm_start(void *);
+
+  // 
+  static uint32_t not_yet_implemented(const std::string& object_name, const 
SaImmAttrModificationT_2* imm_attr);
+  static uint32_t update_health_check_type(const std::string& object_name, 
const SaImmAttrModificationT_2* imm_attr);
+
+  // 
+  static SaVersionT immVersion_;
+  static SaImmOiHandleT immOiHandle_;
+  static SaImmOiHandleT immOmHandle_;
+  static SaSelectionObjectT imm_sel_obj_;
+  static UpdateFn update_callback_[AVSV_SA_AMF_CLASS_MAX];
+  static const char *avnd_class_names_[];
+ private:
+  static SaAisErrorT imm_init();
+  static void imm_main();
+  static SaAisErrorT imm_applier_set();
+  static const SaImmOiCallbacksT_2 avnd_callbacks_;
+  
+  //
+  AvndImm();
+  AvndImm(const AvndImmUtil&);
+  void operator=(const AvndImm&);
+};
+
+//
+extern uint32_t avnd_evt_imm_evh(AVND_CB *cb, AVND_EVT *evt);
+extern uint32_t avnd_create_imm_thread();
+
+#endif /* __cplusclpus */
+
+#endif /* AVND_IMM_H */
+
diff --git a/osaf/services/saf/amf/amfnd/main.cc 
b/osaf/services/saf/amf/amfnd/main.cc
--- a/osaf/services/saf/amf/amfnd/main.cc
+++ b/osaf/services/saf/amf/amfnd/main.cc
@@ -31,6 +31,7 @@
 #include "immutil.h"
 #include "logtrace.h"
 #include "nid_api.h"
+#include "avnd_imm.h"
 
 #define FD_MBX   0
 #define FD_TERM  1
@@ -117,7 +118,8 @@ extern const AVND_EVT_HDLR g_avnd_func_l
        avnd_evt_comp_pres_fsm_evh,     /* AVND_EVT_COMP_PRES_FSM_EV */
        avnd_evt_last_step_term_evh,    /* AVND_EVT_LAST_STEP_TERM */
        avnd_evt_pid_exit_evh,  /* AVND_EVT_PID_EXIT */
-       avnd_evt_tmr_qscing_cmpl_evh    /* AVND_EVT_TMR_QSCING_CMPL */
+       avnd_evt_tmr_qscing_cmpl_evh,   /* AVND_EVT_TMR_QSCING_CMPL */
+       avnd_evt_imm_evh                /* AVND_EVT_IMML */
 };
 
 /* global task handle */
@@ -273,6 +275,12 @@ uint32_t avnd_create(void)
                rc = NCSCC_RC_FAILURE;
                goto done;
        }
+               
+       rc = avnd_create_imm_thread();
+       if (NCSCC_RC_SUCCESS != rc) {
+               rc = NCSCC_RC_FAILURE;
+               goto done;
+       }
 
 done:
        TRACE_LEAVE();

------------------------------------------------------------------------------
Time is money. Stop wasting it! Get your web API in 5 minutes.
www.restlet.com/download
http://p.sf.net/sfu/restlet
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to