/*
 * This function shall change when the CPM has a devoted queue to handle the death & leave 
 * Notifications. The pRecvParam shall be of use then for queuing.
 */
ClRcT clEoProcessIocRecvPortNotification(ClEoExecutionObjT* pThis, ClBufferHandleT eoRecvMsg, ClUint8T priority, ClUint8T protoType, ClUint32T length, ClIocPhysicalAddressT srcAddr)
{
    ClRcT rc = CL_OK;

    ClIocNotificationT notificationInfo = {0};
    ClUint32T msgLength = sizeof(ClIocNotificationT);
    ClIocNotificationIdT notificationId = 0;
    ClUint32T protoVersion = 0;

    CL_EO_LIB_VERIFY();

    rc = clBufferNBytesRead(eoRecvMsg, (ClUint8T *)&notificationInfo,
            &msgLength);
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("EO: clBufferNBytesRead() Failed, rc=[0x%x]\n",
                 rc));
        goto out_delete;
    }
    
    protoVersion = ntohl(notificationInfo.protoVersion);
    if(protoVersion != CL_IOC_NOTIFICATION_VERSION)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                       ("EO: Ioc recv notification received with version [%d]. Supported [%d]\n",
                        protoVersion, CL_IOC_NOTIFICATION_VERSION));
        goto out_delete;
    }

    notificationId = ntohl(notificationInfo.id); 

    switch(notificationId)
    {
        case CL_IOC_SENDQ_WM_NOTIFICATION:
            if(gIsNodeRepresentative == CL_FALSE)
            {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Got sendq wm notification for non-node representative\n"));
                rc = CL_EO_RC(CL_ERR_BAD_OPERATION);
                goto out_delete;
            }
            /*fall through*/
        case CL_IOC_COMM_PORT_WM_NOTIFICATION:
            {
                ClIocNodeAddressT nodeId = 0;
                ClIocPortT portId = ntohl(notificationInfo.nodeAddress.iocPhyAddress.portId);

                ClIocNodeAddressT nodeAddress = ntohl(notificationInfo.nodeAddress.iocPhyAddress.nodeAddress);

                CL_CPM_IOC_ADDRESS_SLOT_GET(nodeAddress,nodeId); 

                rc = clEoIocWMNotification(CL_CID_IOC,portId,nodeId,&notificationInfo);
                if (rc != CL_OK)
                {
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                            ("EO: clEoIocWMNotification() Failed, rc=[0x%x]\n",
                             rc));
                    goto out_delete;
                }
            }
            break;
        case CL_IOC_NODE_ARRIVAL_NOTIFICATION:
        case CL_IOC_NODE_LINK_UP_NOTIFICATION:
        case CL_IOC_COMP_ARRIVAL_NOTIFICATION:
            /* Need to add functionality if the components wants a specific operation...*/
            clEoClientNotification(&notificationInfo);
            rc = CL_OK;
            break;
        case CL_IOC_NODE_LEAVE_NOTIFICATION:
        case CL_IOC_NODE_LINK_DOWN_NOTIFICATION:
        case CL_IOC_COMP_DEATH_NOTIFICATION:
            rc = clBufferDelete(&eoRecvMsg);
            CL_ASSERT(rc == CL_OK);
            rc = clRmdDatabaseCleanup(pThis->rmdObj, &notificationInfo);
            clEoClientNotification(&notificationInfo);
            return rc;
        default:
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Invalid notification id[%d]\n",
                        notificationId));
            rc = CL_EO_RC(CL_ERR_BAD_OPERATION);
            goto out_delete; 
    }

out_delete:
    clBufferDelete(&eoRecvMsg);

    return rc;
}
ClRcT cpmUpdateTL(ClAmsHAStateT haState)
{
    ClIocTLInfoT tlInfo = {0};
    ClRcT rc = CL_OK;
    ClIocNodeAddressT localAddr = clIocLocalAddressGet();
    /*
     * Populate the TL structure 
     */
    cpmGetOwnLogicalAddress(&(tlInfo.logicalAddr));
    
    /*
     * CPM's component ID is slot number shifted
     * by CL_CPM_IOC_SLOT_BITS
     */
    CL_CPM_IOC_ADDRESS_SLOT_GET(clAspLocalId, tlInfo.compId);
    tlInfo.compId = tlInfo.compId << CL_CPM_IOC_SLOT_BITS;

    tlInfo.contextType = CL_IOC_TL_GLOBAL_SCOPE;
    tlInfo.physicalAddr.nodeAddress = localAddr;
    tlInfo.physicalAddr.portId = CL_IOC_CPM_PORT;
    tlInfo.haState = haState;

    if (haState == CL_AMS_HA_STATE_ACTIVE)
    {
        tlInfo.haState = CL_IOC_TL_ACTIVE;

        if( (ClInt32T) gpClCpm->activeMasterNodeId != -1)
        {
            clLogDebug(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
                       "Deregistering TL entry for node [%d]",
                       gpClCpm->activeMasterNodeId);

            clIocTransparencyDeregister((gpClCpm->activeMasterNodeId) <<
                                        CL_CPM_IOC_SLOT_BITS);
        }
    }
    else if(haState == CL_AMS_HA_STATE_STANDBY)
    {
        tlInfo.haState = CL_IOC_TL_STDBY;
    }

    clLogMultiline(CL_LOG_SEV_DEBUG, CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
                   "Updating transparency layer information for node [%s] -- \n"
                   "Component ID : [%#x] \n"
                   "Context type : [%s] \n"
                   "Node address : [%d] \n"
                   "Port ID : [%d] \n"
                   "HA state : [%s]",
                   gpClCpm->pCpmLocalInfo->nodeName,
                   tlInfo.compId,
                   tlInfo.contextType == CL_IOC_TL_GLOBAL_SCOPE ? "Global" :
                   "Local",
                   tlInfo.physicalAddr.nodeAddress,
                   tlInfo.physicalAddr.portId,
                   tlInfo.haState == CL_IOC_TL_ACTIVE ? "Active" : "Standby");

    /*
     * Update the TL with the CPM's logical address 
     */
    rc = clIocTransparencyRegister(&tlInfo);
    if(haState == CL_AMS_HA_STATE_ACTIVE)
    {
        /*
         * Reset the master segment cache for all components
         */
        clIocMasterCacheSet(localAddr);
    }
    else
    {
        clIocMasterCacheReset();
    }

    if (CL_IOC_ERR_TL_DUPLICATE_ENTRY == CL_GET_ERROR_CODE(rc)
        ||
        CL_ERR_ALREADY_EXIST == CL_GET_ERROR_CODE(rc))
    {
        clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
                     "Transparency register returned "
                     "duplicate entry for node address [%d]",
                     tlInfo.physicalAddr.nodeAddress);
        return CL_OK;
    }

    return rc;
}