osaf/services/saf/amf/amfnd/amfnd.cc            |    2 +
 osaf/services/saf/amf/amfnd/cbq.cc              |   23 +++-
 osaf/services/saf/amf/amfnd/comp.cc             |   42 ++++++
 osaf/services/saf/amf/amfnd/compdb.cc           |    4 +
 osaf/services/saf/amf/amfnd/err.cc              |    4 +-
 osaf/services/saf/amf/amfnd/evt.cc              |    2 +
 osaf/services/saf/amf/amfnd/include/avnd_cb.h   |    2 +
 osaf/services/saf/amf/amfnd/include/avnd_comp.h |    2 +-
 osaf/services/saf/amf/amfnd/include/avnd_err.h  |    2 +
 osaf/services/saf/amf/amfnd/include/avnd_evt.h  |    1 +
 osaf/services/saf/amf/amfnd/include/avnd_mds.h  |    6 +-
 osaf/services/saf/amf/amfnd/include/avnd_su.h   |    2 +
 osaf/services/saf/amf/amfnd/main.cc             |    1 +
 osaf/services/saf/amf/amfnd/mds.cc              |   56 ++++++++-
 osaf/services/saf/amf/amfnd/su.cc               |  150 ++++++++++++++++++++++++
 osaf/services/saf/amf/amfnd/util.cc             |   38 +++++-
 16 files changed, 325 insertions(+), 12 deletions(-)


Contains changes related to:
1)Upong receving CSI attribute list, update own databae with modified 
information.
  If compoent has registered with new callback OsafCsiAttributeChangeCallbackT,
  then send callback OsafCsiAttributeChangeCallbackT to AMF agent.
  TODO: For Non Proxied NPI component run INSTANTIATE command.
2)AMFND now maintains MDS install version of AMF AGENTs in
        std::map<MDS_DEST, MDS_SVC_PVT_SUB_PART_VER> agent_mds_ver_db.
  It will be updated whenever AMFND gets MDS_UP and MDS_DOWN for AMF Agent.
3)AMFND maintains now SAF version for each registered component.
  AMFND will get it from Agent through existing component registeration message.

diff --git a/osaf/services/saf/amf/amfnd/amfnd.cc 
b/osaf/services/saf/amf/amfnd/amfnd.cc
--- a/osaf/services/saf/amf/amfnd/amfnd.cc
+++ b/osaf/services/saf/amf/amfnd/amfnd.cc
@@ -24,6 +24,8 @@
 ****************************************************************************/
 #include "avnd.h"
 
+//Remember MDS install version of Agents. It can be used to send msg to Agent 
based on their versions.
+std::map<MDS_DEST, MDS_SVC_PVT_SUB_PART_VER> agent_mds_ver_db;
 extern const AVND_EVT_HDLR g_avnd_func_list[AVND_EVT_MAX];
 
 static uint32_t avnd_evt_avnd_avnd_api_msg_hdl(AVND_CB *cb, AVND_EVT *evt);
diff --git a/osaf/services/saf/amf/amfnd/cbq.cc 
b/osaf/services/saf/amf/amfnd/cbq.cc
--- a/osaf/services/saf/amf/amfnd/cbq.cc
+++ b/osaf/services/saf/amf/amfnd/cbq.cc
@@ -398,6 +398,22 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *
                }
                break;
 
+       case AVSV_AMF_CSI_ATTR_CHANGE:
+               csi = m_AVND_COMPDB_REC_CSI_GET(*comp, 
cbk_rec->cbk_info->param.csi_attr_change.csi_name);
+               if (!csi)
+                       LOG_ER("'%s', not found", 
cbk_rec->cbk_info->param.csi_attr_change.csi_name.value);
+               avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+               if (m_AVND_TMR_IS_ACTIVE(cbk_rec->resp_tmr)) {
+                       m_AVND_TMR_COMP_CBK_RESP_STOP(cb, *cbk_rec)
+               }
+                if (SA_AIS_OK != resp->err) {
+                       //generate a failure report.
+                        err_info.src = AVND_ERR_SRC_CBK_CSI_ATTR_CHANGE_FAILED;
+                        err_info.rec_rcvr.avsv_ext = 
static_cast<AVSV_ERR_RCVR>(comp->err_info.def_rec);
+                        rc = avnd_err_process(cb, comp, &err_info);
+                } 
+
+               break;
        case AVSV_AMF_CSI_SET:
 
                if (m_AVND_COMP_TYPE_IS_PROXIED(comp) && 
!m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp)) {
@@ -592,6 +608,9 @@ uint32_t avnd_evt_tmr_cbk_resp_evh(AVND_
                case AVSV_AMF_CSI_REM:
                        err_info.src = AVND_ERR_SRC_CBK_CSI_REM_TIMEOUT;
                        break;
+               case AVSV_AMF_CSI_ATTR_CHANGE:
+                       err_info.src = AVND_ERR_SRC_CBK_CSI_ATTR_CHANGE_TIMEOUT;
+                       break;
                default:
                        
LOG_ER("%s,%u,type=%u",__FUNCTION__,__LINE__,rec->cbk_info->type);
                        err_info.src = AVND_ERR_SRC_CBK_CSI_SET_TIMEOUT;
@@ -1033,7 +1052,9 @@ void avnd_comp_cbq_csi_rec_del(AVND_CB *
                        if (((AVSV_AMF_CSI_SET == info->type) &&
                             (0 == 
m_CMP_HORDER_SANAMET(info->param.csi_set.csi_desc.csiName, *csi_name))) ||
                            ((AVSV_AMF_CSI_REM == info->type) &&
-                            (0 == 
m_CMP_HORDER_SANAMET(info->param.csi_rem.csi_name, *csi_name))))
+                            (0 == 
m_CMP_HORDER_SANAMET(info->param.csi_rem.csi_name, *csi_name))) || 
+                           ((AVSV_AMF_CSI_ATTR_CHANGE == info->type) &&
+                             (0 == 
m_CMP_HORDER_SANAMET(info->param.csi_attr_change.csi_name, *csi_name))))
                                to_del = true;
                }
 
diff --git a/osaf/services/saf/amf/amfnd/comp.cc 
b/osaf/services/saf/amf/amfnd/comp.cc
--- a/osaf/services/saf/amf/amfnd/comp.cc
+++ b/osaf/services/saf/amf/amfnd/comp.cc
@@ -721,6 +721,9 @@ uint32_t avnd_comp_reg_prc(AVND_CB *cb, 
        /* update the comp reg params */
        comp->reg_hdl = reg->hdl;
        comp->reg_dest = *dest;
+       comp->version = reg->version;
+       TRACE("SAF version '%c'.'%u'.'%u'",comp->version.releaseCode,
+                       comp->version.majorVersion, comp->version.minorVersion);
        m_AVND_COMP_REG_SET(comp);
 
        /* if proxied comp, do add to the pxied_list of pxy */
@@ -1893,6 +1896,41 @@ uint32_t avnd_comp_curr_info_del(AVND_CB
        return rc;
 }
 
+/**
+ * @brief Prepares CSI attribute change callback message for amfa with updated 
values.
+ *       Values are updated in csi_rec when AMFND gets it from AMFD.
+ * 
+ * @param  cbk_info (ptr to AVSV_AMF_CBK_INFO) 
+ * @param  comp (ptr to AVND_COMP) 
+ * @param  csi_rec(ptr to AVND_COMP_CSI_REC) 
+ *
+ * @return true/false
+ */
+static void set_params_for_csi_attr_change_cbk(AVSV_AMF_CBK_INFO *cbk_info, 
AVND_COMP *comp, AVND_COMP_CSI_REC *csi_rec)
+{
+        AVSV_CSI_ATTRS attr;
+
+       /* copy the attributes */
+       memset(&attr, 0, sizeof(AVSV_CSI_ATTRS));
+       if (csi_rec->attrs.number != 0) {
+               //Keeping consistency. Why AMFND is using malloc and calloc at 
some places instead new?
+               attr.list = static_cast<AVSV_ATTR_NAME_VAL*>
+                       (calloc(csi_rec->attrs.number, 
sizeof(AVSV_ATTR_NAME_VAL)));
+               osafassert(attr.list != nullptr);
+
+               memcpy(attr.list, csi_rec->attrs.list,
+                               sizeof(AVSV_ATTR_NAME_VAL) 
*csi_rec->attrs.number);
+               attr.number = csi_rec->attrs.number;
+       }
+       /* fill the callback params */
+       cbk_info->type = AVSV_AMF_CSI_ATTR_CHANGE;
+       cbk_info->param.csi_attr_change.csi_name = csi_rec->name;
+       cbk_info->param.csi_attr_change.attrs = attr;
+       /* reset the attr */
+       attr.number = 0;
+       attr.list = 0;
+}
+
 /****************************************************************************
   Name          : avnd_comp_cbk_send
  
@@ -2046,6 +2084,10 @@ uint32_t avnd_comp_cbk_send(AVND_CB *cb,
                m_AVND_AMF_PXIED_COMP_CLEAN_CBK_FILL(*cbk_info, comp->name);
                per = comp->pxied_clean_cbk_timeout;
                break;
+       case AVSV_AMF_CSI_ATTR_CHANGE:
+               set_params_for_csi_attr_change_cbk(cbk_info, comp, csi_rec);
+               per = comp->csi_set_cbk_timeout;
+               break;  
        case AVSV_AMF_PG_TRACK:
        default:
                osafassert(0);
diff --git a/osaf/services/saf/amf/amfnd/compdb.cc 
b/osaf/services/saf/amf/amfnd/compdb.cc
--- a/osaf/services/saf/amf/amfnd/compdb.cc
+++ b/osaf/services/saf/amf/amfnd/compdb.cc
@@ -1785,6 +1785,10 @@ static AVND_COMP *avnd_comp_create(const
        comp->su = su;
        comp->error_report_sent = false;
        comp->admin_oper = false;
+       //Default SAF version.
+       comp->version.releaseCode = 'B';
+       comp->version.majorVersion = 0x01; 
+       comp->version.minorVersion = 0x01; 
 
        if (true == su->su_is_external) {
                m_AVND_COMP_TYPE_SET_EXT_CLUSTER(comp);
diff --git a/osaf/services/saf/amf/amfnd/err.cc 
b/osaf/services/saf/amf/amfnd/err.cc
--- a/osaf/services/saf/amf/amfnd/err.cc
+++ b/osaf/services/saf/amf/amfnd/err.cc
@@ -96,7 +96,9 @@ static const char *g_comp_err[] = {
        "csiRemovecallbackTimeout",
        "csiSetcallbackFailed",
        "csiRemovecallbackFailed",
-       "qscingCompleteTimeout"
+       "qscingCompleteTimeout",
+       "csiAttributeChangeCallbackTimeout",
+       "csiAttributeChangeCallbackFailed"
 };
 
 static const char *g_comp_rcvr[] = {
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
@@ -87,6 +87,7 @@ AVND_EVT *avnd_evt_create(AVND_CB *cb,
        case AVND_EVT_AVD_ROLE_CHANGE_MSG:
        case AVND_EVT_AVD_ADMIN_OP_REQ_MSG:
        case AVND_EVT_AVD_REBOOT_MSG:
+       case AVND_EVT_AVD_COMPCSI_ASSIGN_MSG:
                evt->info.avd = (AVSV_DND_MSG *)info;
                break;
 
@@ -231,6 +232,7 @@ void avnd_evt_destroy(AVND_EVT *evt)
        case AVND_EVT_AVD_ADMIN_OP_REQ_MSG:
        case AVND_EVT_AVD_HEARTBEAT_MSG:
        case AVND_EVT_AVD_REBOOT_MSG:
+       case AVND_EVT_AVD_COMPCSI_ASSIGN_MSG:
                if (evt->info.avd)
                        avsv_dnd_msg_free(evt->info.avd);
                break;
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_cb.h 
b/osaf/services/saf/amf/amfnd/include/avnd_cb.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_cb.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_cb.h
@@ -32,6 +32,7 @@
  */
 #ifndef AVND_CB_H
 #define AVND_CB_H
+#include <map>
 
 
 typedef struct avnd_cb_tag {
@@ -145,5 +146,6 @@ typedef struct avnd_cb_tag {
 void cb_increment_su_failover_count(AVND_CB& cb, const AVND_SU& su);
 
 extern AVND_CB *avnd_cb;
+extern std::map<MDS_DEST, MDS_SVC_PVT_SUB_PART_VER> agent_mds_ver_db;
 
 #endif
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_comp.h 
b/osaf/services/saf/amf/amfnd/include/avnd_comp.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_comp.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_comp.h
@@ -401,7 +401,7 @@ typedef struct avnd_comp_tag {
 
        std::bitset<NumAttrs> *use_comptype_attr;
        SaInvocationT term_cbq_inv_value; /* invocation value for termination 
callback. */
-
+       SaVersionT version; //SAF version of comp.
 } AVND_COMP;
 
 #define AVND_COMP_NULL ((AVND_COMP *)0)
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_err.h 
b/osaf/services/saf/amf/amfnd/include/avnd_err.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_err.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_err.h
@@ -68,6 +68,8 @@ typedef enum avnd_err_src {
        AVND_ERR_SRC_CBK_CSI_REM_FAILED,        /* AMF callback failed */
        /* Add other sources of error detection */
        AVND_ERR_SRC_QSCING_COMPL_TIMEOUT,      /* AMF qscing complete times 
out */
+       AVND_ERR_SRC_CBK_CSI_ATTR_CHANGE_TIMEOUT,/* CSI attr change callback 
times out.*/
+       AVND_ERR_SRC_CBK_CSI_ATTR_CHANGE_FAILED,        /* CSI attr change 
callback failed.*/
 
        AVND_ERR_SRC_MAX
 } AVND_ERR_SRC;
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
@@ -52,6 +52,7 @@ typedef enum avnd_evt_type {
        AVND_EVT_AVD_ADMIN_OP_REQ_MSG,
        AVND_EVT_AVD_HEARTBEAT_MSG,
        AVND_EVT_AVD_REBOOT_MSG,
+       AVND_EVT_AVD_COMPCSI_ASSIGN_MSG,
        AVND_EVT_AVD_MAX,
 
        /* AvA event types */
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_mds.h 
b/osaf/services/saf/amf/amfnd/include/avnd_mds.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_mds.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_mds.h
@@ -31,16 +31,16 @@
 #define AVND_MDS_H
 
 /* In Service upgrade support */
-#define AVND_MDS_SUB_PART_VERSION   6
+#define AVND_MDS_SUB_PART_VERSION   7
 
 #define AVND_AVD_SUBPART_VER_MIN   1
-#define AVND_AVD_SUBPART_VER_MAX   6
+#define AVND_AVD_SUBPART_VER_MAX   7
 
 #define AVND_AVND_SUBPART_VER_MIN   1
 #define AVND_AVND_SUBPART_VER_MAX   1
 
 #define AVND_AVA_SUBPART_VER_MIN   1
-#define AVND_AVA_SUBPART_VER_MAX   1
+#define AVND_AVA_SUBPART_VER_MAX   2
 
 #define AVND_CLA_SUBPART_VER_MIN   1
 #define AVND_CLA_SUBPART_VER_MAX   1
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_su.h 
b/osaf/services/saf/amf/amfnd/include/avnd_su.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_su.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_su.h
@@ -49,6 +49,7 @@ struct avnd_cb_tag;
  * not a part of SU-SI parameters. Concealing those params thru this typedef.
  */
 typedef AVSV_D2N_INFO_SU_SI_ASSIGN_MSG_INFO AVND_SU_SI_PARAM;
+typedef AVSV_D2N_COMPCSI_ASSIGN_MSG_INFO AVND_COMP_CSI_PARAMS_INFO;
 
 /* declaration clc event handler */
 typedef uint32_t (*AVND_SU_PRES_FSM_FN) (struct avnd_cb_tag *, struct 
avnd_su_tag *, AVND_COMP *);
@@ -420,4 +421,5 @@ bool all_csis_in_restarting_state(const 
 extern AVND_SU *sudb_rec_get(NCS_PATRICIA_TREE *sudb, const SaNameT *name);
 extern AVND_SU *sudb_rec_get_next(NCS_PATRICIA_TREE *sudb, uint8_t *name);
 extern void sudb_rec_comp_add(AVND_SU *su, AVND_COMP *comp, uint32_t *rc);
+uint32_t avnd_evt_avd_compcsi_evh(struct avnd_cb_tag *cb, struct avnd_evt_tag 
*evt);
 #endif
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
@@ -68,6 +68,7 @@ extern const AVND_EVT_HDLR g_avnd_func_l
        avnd_evt_avd_admin_op_req_evh,  /* AVND_EVT_AVD_ADMIN_OP_REQ_MSG */
        avnd_evt_avd_hb_evh,            /* AVND_EVT_AVD_HEARTBEAT_MSG */
        avnd_evt_avd_reboot_evh,            /* /AVND_EVT_AVD_REBOOT_MSG */
+       avnd_evt_avd_compcsi_evh, //AVND_EVT_AVD_COMPCSI_ASSIGN_MSG
 
        /* AvA event types */
        avnd_evt_ava_finalize_evh,      /* AVND_EVT_AVA_AMF_FINALIZE */
diff --git a/osaf/services/saf/amf/amfnd/mds.cc 
b/osaf/services/saf/amf/amfnd/mds.cc
--- a/osaf/services/saf/amf/amfnd/mds.cc
+++ b/osaf/services/saf/amf/amfnd/mds.cc
@@ -41,14 +41,14 @@
 const MDS_CLIENT_MSG_FORMAT_VER avnd_avd_msg_fmt_map_table[] = {
        AVSV_AVD_AVND_MSG_FMT_VER_1, AVSV_AVD_AVND_MSG_FMT_VER_2,
        AVSV_AVD_AVND_MSG_FMT_VER_3, AVSV_AVD_AVND_MSG_FMT_VER_4,
-       AVSV_AVD_AVND_MSG_FMT_VER_4, AVSV_AVD_AVND_MSG_FMT_VER_6
+       AVSV_AVD_AVND_MSG_FMT_VER_4, AVSV_AVD_AVND_MSG_FMT_VER_6, 
AVSV_AVD_AVND_MSG_FMT_VER_7
 };
 
 /* messages from director */
 const MDS_CLIENT_MSG_FORMAT_VER avd_avnd_msg_fmt_map_table[] = {
        AVSV_AVD_AVND_MSG_FMT_VER_1, AVSV_AVD_AVND_MSG_FMT_VER_2,
        AVSV_AVD_AVND_MSG_FMT_VER_3, AVSV_AVD_AVND_MSG_FMT_VER_4,
-       AVSV_AVD_AVND_MSG_FMT_VER_5, AVSV_AVD_AVND_MSG_FMT_VER_6
+       AVSV_AVD_AVND_MSG_FMT_VER_5, AVSV_AVD_AVND_MSG_FMT_VER_6, 
AVSV_AVD_AVND_MSG_FMT_VER_7
 };
 
 const MDS_CLIENT_MSG_FORMAT_VER avnd_avnd_msg_fmt_map_table[] = {
@@ -56,7 +56,7 @@ const MDS_CLIENT_MSG_FORMAT_VER avnd_avn
 };
 
 const MDS_CLIENT_MSG_FORMAT_VER avnd_ava_msg_fmt_map_table[] = {
-       AVSV_AVND_AVA_MSG_FMT_VER_1
+       AVSV_AVND_AVA_MSG_FMT_VER_1, AVSV_AVND_AVA_MSG_FMT_VER_2
 };
 
 /* static function declarations */
@@ -399,8 +399,11 @@ uint32_t avnd_mds_rcv(AVND_CB *cb, MDS_C
        /* determine the event type */
        switch (msg.type) {
        case AVND_MSG_AVD:
-                type = static_cast<AVND_EVT_TYPE>((msg.info.avd->msg_type - 
AVSV_D2N_NODE_UP_MSG) + AVND_EVT_AVD_NODE_UP_MSG);
 
+               if (msg.info.avd->msg_type == AVSV_D2N_COMPCSI_ASSIGN_MSG)
+                       type = AVND_EVT_AVD_COMPCSI_ASSIGN_MSG;
+               else 
+                       type = 
static_cast<AVND_EVT_TYPE>((msg.info.avd->msg_type - AVSV_D2N_NODE_UP_MSG) + 
AVND_EVT_AVD_NODE_UP_MSG);
                break;
 
        case AVND_MSG_AVA:
@@ -537,6 +540,7 @@ uint32_t avnd_mds_svc_evt(AVND_CB *cb, M
 
                case NCSMDS_SVC_ID_AVA:
                        /*  New AvA has come up. Dont do anything now */
+                       agent_mds_ver_db[evt_info->i_dest] = 
(MDS_SVC_PVT_SUB_PART_VER)evt_info->i_rem_svc_pvt_ver;
                        break;
 
                case NCSMDS_SVC_ID_AVND:
@@ -583,6 +587,7 @@ uint32_t avnd_mds_svc_evt(AVND_CB *cb, M
                        break;
 
                case NCSMDS_SVC_ID_AVA:
+                       agent_mds_ver_db.erase(evt_info->i_dest);
                        evt = avnd_evt_create(cb, AVND_EVT_MDS_AVA_DN, 0, 
&evt_info->i_dest, 0, 0, 0);
                        break;
 
@@ -779,7 +784,45 @@ uint32_t avnd_mds_flat_enc(AVND_CB *cb, 
 
        return rc;
 }
-
+/**
+ * @brief  Encodes CSI attribute change callback msg.
+ *
+ * @param  uba (ptr to NCS_UBAID).
+ * @param  msg (ptr to AVSV_NDA_AVA_MSG).
+ *
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+static uint32_t enc_csi_attr_change_cbk(NCS_UBAID *uba, AVSV_NDA_AVA_MSG *msg)
+{
+       AVSV_AMF_CSI_ATTR_CHANGE_PARAM *csi_attr_change = 
&msg->info.cbk_info->param.csi_attr_change;
+       uint8_t *p8;
+       uint16_t len;
+       uint32_t rc = NCSCC_RC_SUCCESS, i;
+       SaStringT value = nullptr;
+       if (csi_attr_change->attrs.number == 0)
+               goto done;
+       for(i=0; i<csi_attr_change->attrs.number; i++) {
+               rc = ncs_encode_n_octets_in_uba(uba,
+                        (uint8_t *)&csi_attr_change->attrs.list[i].name, 
sizeof(SaNameT));
+               if (NCSCC_RC_SUCCESS != rc)
+                       goto done;
+               if(!csi_attr_change->attrs.list[i].string_ptr) {
+                       value = new 
char[csi_attr_change->attrs.list[i].value.length+1]();
+                       strcpy(value, (char 
*)csi_attr_change->attrs.list[i].value.value);
+               } else {
+                       value = csi_attr_change->attrs.list[i].string_ptr;
+               }
+               len = strlen(value);
+               p8 = ncs_enc_reserve_space(uba, 2);
+               ncs_encode_16bit(&p8, len);
+               ncs_enc_claim_space(uba, 2);
+               rc = ncs_encode_n_octets_in_uba(uba, (uint8_t *)value, (len + 
1));
+               if (NCSCC_RC_SUCCESS != rc)
+                       goto done;
+       }
+done:
+       return rc;
+}
 /****************************************************************************
   Name          : avnd_mds_flat_ava_enc
  
@@ -820,6 +863,9 @@ uint32_t avnd_mds_flat_ava_enc(AVND_CB *
                                goto done;
 
                        switch (cbk_info->type) {
+                       case AVSV_AMF_CSI_ATTR_CHANGE:
+                               rc = enc_csi_attr_change_cbk(enc_info->io_uba, 
ava);
+                               break;  
                        case AVSV_AMF_CSI_SET:
                                if (cbk_info->param.csi_set.attrs.number) {
                                        for(i=0; 
i<cbk_info->param.csi_set.attrs.number; i++) {
diff --git a/osaf/services/saf/amf/amfnd/su.cc 
b/osaf/services/saf/amf/amfnd/su.cc
--- a/osaf/services/saf/amf/amfnd/su.cc
+++ b/osaf/services/saf/amf/amfnd/su.cc
@@ -864,3 +864,153 @@ bool isRestartSet(const AVND_SU *su)
 {
        return (m_AVND_SU_IS_RESTART(su));
 }
+
+/**
+ * @brief  Processes compcsi msg based on the action (msg_type). 
+ *             As of now only try to send csi attribute change callback.
+ * @param  comp (ptr to AVND_COMP)
+ * @param  csi_rec (ptr to AVND_COMP_CSI_REC)
+ * @param  param (ptr to AVND_COMP_CSI_PARAMS_INFO)
+ *
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+static uint32_t avnd_process_comp_csi_msg (AVND_COMP *comp, AVND_COMP_CSI_REC 
*csi_rec,
+               AVND_COMP_CSI_PARAMS_INFO *param)
+{
+       uint32_t rc = NCSCC_RC_SUCCESS;
+       std::map<MDS_DEST, MDS_SVC_PVT_SUB_PART_VER>::iterator iter;    
+
+       /*
+          Callback is sent in the following cases:
+               -a PI comp: CSI is assigned to this component.
+               -a proxied PI comp: callback is sent to its proxy.
+               -a proxied NPI:callback is sent to its proxy.
+          For a Non-proxied NPI comp, INSANTIATE command (CLC-CLI) will be 
invoked.
+          Callback can be sent only when Agent version is B.04.02 in which 
case 
+          minimum MDS install version must be AVSV_AVND_AVA_MSG_FMT_VER_2.
+        */
+       if ((m_AVND_COMP_TYPE_IS_SAAWARE(comp)) || 
+                               (m_AVND_COMP_TYPE_IS_PROXIED(comp) &&
+                                m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp))) {
+               iter = agent_mds_ver_db.find(csi_rec->comp->reg_dest);
+               if (iter == agent_mds_ver_db.end()) {
+                       TRACE("Component is not registered");
+                       rc = NCSCC_RC_FAILURE;
+                       goto done;
+               }
+               if ((iter->second < AVSV_AVND_AVA_MSG_FMT_VER_2) ||
+                               (comp->version.releaseCode != 'B') ||
+                               (comp->version.majorVersion != 0x04) || 
+                               (comp->version.minorVersion != 0x02)) {
+                       TRACE("Component version is not B.04.02");
+                       rc = NCSCC_RC_SUCCESS;
+                       goto done;
+               }
+       }
+
+       switch (param->msg_act) {
+       case AVSV_COMPCSI_ATTR_CHANGE_AND_NO_ACK:
+               if (csi_rec->attrs.list != nullptr)
+                       free (csi_rec->attrs.list);
+               csi_rec->attrs.number = param->info.attrs.number;
+               csi_rec->attrs.list = param->info.attrs.list;
+               param->info.attrs.number = 0;
+               param->info.attrs.list = 0;
+               //do not take any action if comp is failed.
+               if (m_AVND_COMP_IS_FAILED(comp)) {
+                       TRACE_2("Failed comp, not sending csi attrbute change 
cbk.");
+                       goto done;
+               }
+               //Do not issue callback if csi is being removed. 
+               if (m_AVND_COMP_CSI_CURR_ASSIGN_STATE_IS_REMOVING(csi_rec) || 
+                       m_AVND_COMP_CSI_CURR_ASSIGN_STATE_IS_REMOVED(csi_rec)) {
+                       TRACE_2("CSI removing or removed, not sending csi 
attrbute change cbk.");
+                       goto done;
+               }
+
+               if (m_AVND_COMP_TYPE_IS_PROXIED(comp) || 
m_AVND_COMP_TYPE_IS_SAAWARE(comp)) {
+                       TRACE_2("Proxied (NPI or PI) or a SA-Aware component.");
+                       rc = avnd_comp_cbk_send(avnd_cb, comp, 
AVSV_AMF_CSI_ATTR_CHANGE, 0, csi_rec);
+               } else {
+                       //A NPI comp is terminated in quiesced and quiecing 
state.
+                       if 
(!m_AVND_COMP_CSI_CURR_ASSIGN_STATE_IS_ASSIGNED(csi_rec) &&
+                                       (csi_rec->si->curr_state != 
SA_AMF_HA_ACTIVE)) {
+                               TRACE_2("NPI comp in improper state, not 
running inst command.");
+                               goto done;
+                       }
+                       if (true) {
+                               TRACE_2("Values will come into effect in next 
instantiation");
+                               goto done;
+                       }
+                       //ToDo for a NonProxied NPI component: Fine tuning of 
success case and failure handling..       
+                       rc = avnd_comp_clc_cmd_execute(avnd_cb, comp, 
AVND_COMP_CLC_CMD_TYPE_INSTANTIATE);
+                       if (NCSCC_RC_SUCCESS == rc)
+                               m_GET_TIME_STAMP(comp->clc_info.inst_cmd_ts);
+               }       
+               if (NCSCC_RC_SUCCESS != rc)
+                       goto done;
+                break;
+        default:
+                TRACE_LEAVE();
+                return NCSCC_RC_FAILURE;
+                break;
+        }
+done:
+       return rc;
+}
+
+/**
+ * @brief  Processes compcsi message from AMFD.
+ *        As of now expects only message for CSI attribute change.
+ * @param  cb (ptr to AVND_CB)
+ * @param  evt(ptr to AVND_EVT)
+ *
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+uint32_t avnd_evt_avd_compcsi_evh(AVND_CB *cb, AVND_EVT *evt)
+{
+       AVND_COMP_CSI_PARAMS_INFO *compcsi_info = 
&evt->info.avd->msg_info.d2n_compcsi_assign_msg_info;
+       AVND_COMP_CSI_REC *csi_rec = nullptr;
+       AVND_COMP *comp = nullptr;
+       //AVND_SU_SIQ_REC *siq = 0;
+       uint32_t rc = NCSCC_RC_SUCCESS;
+
+       TRACE_ENTER2("'%s', '%s', act:%u", compcsi_info->comp_name.value, 
compcsi_info->csi_name.value,
+                        compcsi_info->msg_act);
+       comp = m_AVND_COMPDB_REC_GET(cb->compdb, compcsi_info->comp_name);
+       if (!comp) {
+               LOG_ER("compcsi_evh: '%s' not found, action:%u",
+                               compcsi_info->comp_name.value, 
compcsi_info->msg_act);
+               goto done;
+       }
+
+       if ((cb->term_state == AVND_TERM_STATE_OPENSAF_SHUTDOWN_INITIATED) ||
+                       (cb->term_state == 
AVND_TERM_STATE_OPENSAF_SHUTDOWN_STARTED)) {
+               LOG_NO("Shutting started : Ignoring re-assignment for 
comp'%s'", comp->name.value);
+               goto done;
+       }
+
+       avnd_msgid_assert(compcsi_info->msg_id);
+       cb->rcv_msg_id = compcsi_info->msg_id;
+
+        csi_rec = avnd_compdb_csi_rec_get(cb, &compcsi_info->comp_name, 
&compcsi_info->csi_name);
+        if (csi_rec == nullptr) {
+                TRACE("csi rec get Failed.");
+                rc = NCSCC_RC_FAILURE;
+                goto done;
+        }
+       if (cb->term_state == AVND_TERM_STATE_NODE_FAILOVER_TERMINATED) {
+               if (compcsi_info->msg_act == 
AVSV_COMPCSI_ATTR_CHANGE_AND_NO_ACK)
+                       //A message witn no ack, no need to respond to AFMD.
+                       TRACE_2("AVND is in failover escalation, not sending 
csi attrbute change cbk.");
+                       goto done;
+       } else {
+               rc = avnd_process_comp_csi_msg(comp, csi_rec, compcsi_info);
+       }
+
+done:
+       TRACE_LEAVE2("%u", rc);
+       return rc;
+}
+
+
diff --git a/osaf/services/saf/amf/amfnd/util.cc 
b/osaf/services/saf/amf/amfnd/util.cc
--- a/osaf/services/saf/amf/amfnd/util.cc
+++ b/osaf/services/saf/amf/amfnd/util.cc
@@ -564,6 +564,33 @@ uint32_t amf_cbk_copy(AVSV_AMF_CBK_INFO 
                }
                break;
 
+       case AVSV_AMF_CSI_ATTR_CHANGE:
+               memset(&(*o_dcbk)->param.csi_attr_change.csi_name, 0, 
sizeof(SaNameT));
+               /* memset avsv & amf csi attr lists */
+               memset(&(*o_dcbk)->param.csi_attr_change.attrs, 0, 
sizeof(AVSV_CSI_ATTRS));
+               memset(&(*o_dcbk)->param.csi_attr_change.csiAttr, 0, 
sizeof(SaAmfCSIAttributeListT));
+               memcpy(&(*o_dcbk)->param.csi_attr_change.csi_name.value,
+                               
scbk->param.csi_attr_change.csi_name.value,scbk->param.csi_attr_change.csi_name.length);
+               /* copy the avsv csi attr list */
+               if (scbk->param.csi_attr_change.attrs.number > 0) {
+                       (*o_dcbk)->param.csi_attr_change.attrs.list = 
static_cast<AVSV_ATTR_NAME_VAL*>
+                               
(calloc(scbk->param.csi_attr_change.attrs.number, sizeof(AVSV_ATTR_NAME_VAL)));
+                       osafassert((*o_dcbk)->param.csi_attr_change.attrs.list 
!= nullptr);
+
+                       for (uint32_t i = 0; i < 
scbk->param.csi_attr_change.attrs.number; ++i) {
+                               (*o_dcbk)->param.csi_attr_change.attrs.list[i] =
+                                       
scbk->param.csi_attr_change.attrs.list[i];
+                       }
+                       (*o_dcbk)->param.csi_attr_change.attrs.number = 
scbk->param.csi_attr_change.attrs.number;
+               }
+
+               /* copy the amf csi attr list */
+               if (scbk->param.csi_attr_change.csiAttr.number > 0) {
+                       
amf_csi_attr_list_copy(&(*o_dcbk)->param.csi_attr_change.csiAttr,
+                                &scbk->param.csi_attr_change.csiAttr);
+                }
+                break;
+
        case AVSV_AMF_CSI_SET:
                /* memset avsv & amf csi attr lists */
                memset(&(*o_dcbk)->param.csi_set.attrs, 0, 
sizeof(AVSV_CSI_ATTRS));
@@ -637,7 +664,16 @@ void amf_cbk_free(AVSV_AMF_CBK_INFO *cbk
                /* free the amf csi attr list */
                
amf_csi_attr_list_free(&cbk_info->param.csi_set.csi_desc.csiAttr);
                break;
-
+       case AVSV_AMF_CSI_ATTR_CHANGE:
+               /* free the avsv csi attr list */
+                if (cbk_info->param.csi_attr_change.attrs.number > 0) {
+                        // AVSV_ATTR_NAME_VAL variables
+                        // are malloc'ed, use free()
+                        free(cbk_info->param.csi_attr_change.attrs.list);
+                }
+                /* free the amf csi attr list */
+                
amf_csi_attr_list_free(&cbk_info->param.csi_attr_change.csiAttr);
+               break;
        default:
                break;
        }

------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to