void safAssignWork(SaInvocationT       invocation,
                   const SaNameT       *compName,
                   SaAmfHAStateT       haState,
                   SaAmfCSIDescriptorT csiDescriptor)
{
    /* Print information about the CSI Set */

    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", 
              compName->length, compName->value, mypid);

    printCSI(csiDescriptor, haState);

    /*
     * Take appropriate action based on state
     */

    switch ( haState )
    {
        /* AMF asks this process to take the standby HA state for the work
           described in the csiDescriptor variable */
        case SA_AMF_HA_ACTIVE:
        {
            /* Typically you would spawn a thread here to initiate active 
               processing of the work. */
            if (csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL)
            {
                ClRcT rc;
                ClCpmCompCSIRefT csiRef = { 0 };
                ClInt32T i;
                rc = clCpmCompCSIList((SaNameT *)compName, &csiRef);
                if(rc != CL_OK)
                {
                    clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc);
                }
                 else
                 {
                      for(i = 0; i < csiRef.numCSIs; ++i)
                      {
                         VirtualIpAddress temp;
                         ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i];

                         clprintf(CL_LOG_SEV_INFO,"Comp [%s], CSI [%s], HA state [%s]",
                             (const char*)compName->value,
                             (const char*)pCSI->csiDescriptor.csiName.value,
                             STRING_HA_STATE((ClUint32T)pCSI->haState));

                         GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp);
                         AddRemVirtualAddress("up",&temp);

                     }
                     if(csiRef.pCSIList)
                       clHeapFree(csiRef.pCSIList);
                }
            }
            else /* SA_AMF_CSI_ADD_ONE */
            {
                 GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
                 AddRemVirtualAddress("up",&gVirtualIp);
            }

            /* The AMF times the interval between the assignment and acceptance
               of the work (the time interval is configurable).
               So it is important to call this saAmfResponse function ASAP.
             */
            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        /* AMF asks this process to take the standby HA state for the work
           described in the csiDescriptor variable */
        case SA_AMF_HA_STANDBY:
        {
            /* If your standby has ongoing maintenance, you would spawn a thread
               here to do it. */

            /* The AMF times the interval between the assignment and acceptance
               of the work (the time interval is configurable).
               So it is important to call this saAmfResponse function ASAP.
             */
            GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
            AddRemVirtualAddress("down",&gVirtualIp);  /* Bring it down just in case it is up from a prior run */
            saAmfResponse(amfHandle, invocation, SA_AIS_OK);  
            break;
        }

        case SA_AMF_HA_QUIESCED:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active or quiescing HA state. The application 
             * must stop work associated with the CSI immediately.
             */
            if (csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ONE)
            {
                AddRemVirtualAddress("down",&gVirtualIp);
            }           
            else if (csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL)
            {                
                ClRcT rc;
                ClCpmCompCSIRefT csiRef = { 0 };
                ClInt32T i;
                rc = clCpmCompCSIList((SaNameT *)compName, &csiRef);
                if(rc != CL_OK)
                {
                    clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc);
                }
                else
                {
                    for(i = 0; i < csiRef.numCSIs; ++i)
                    {
                        VirtualIpAddress temp;
                        ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i];

                        clprintf(CL_LOG_SEV_INFO,"Comp [%s ], CSI [%s], HA state [%s]",
                                compName->value, 
                                pCSI->csiDescriptor.csiName.value,
                                STRING_HA_STATE((ClUint32T)pCSI->haState));

                        GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp);
                        AddRemVirtualAddress("down",&temp);

                    }
                    if(csiRef.pCSIList)
                    clHeapFree(csiRef.pCSIList);
                }
            }
            else /* SA_AMF_CSI_ADD_ONE */
            {
                VirtualIpAddress temp;
                GetVirtualAddressInfo(&csiDescriptor, &temp);
                AddRemVirtualAddress("down",&temp);
            }
            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_QUIESCING:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active HA state. The application must stop work
             * associated with the CSI gracefully and not accept any new
             * workloads while the work is being terminated.
             */

            /* There are two typical cases for quiescing.  Chooose one!
               CASE 1: Its possible to quiesce rapidly within this thread context */
            if (1)
              {
              /* App code here: Now finish your work and cleanly stop the work*/
            
              /* Call saAmfCSIQuiescingComplete when stopping the work is done */
              saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK);
              }
            else
              {
              /* CASE 2: You can't quiesce within this thread context or quiesce
               rapidly. */

              /* Respond immediately to the quiescing request */
              saAmfResponse(amfHandle, invocation, SA_AIS_OK);

              /* App code here: Signal or spawn a thread to cleanly stop the work*/
              /* When that thread is done, it should call:
                 saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK);
              */
              }

            break;
        }

        default:
        {
            assert(0);
            break;
        }
    }

    return;
}
void safAssignWork(SaInvocationT       invocation,
                   const SaNameT       *compName,
                   SaAmfHAStateT       haState,
                   SaAmfCSIDescriptorT csiDescriptor)
{
    /* Print information about the CSI Set */

    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", 
              compName->length, compName->value, mypid);

    printCSI(csiDescriptor, haState);

    /*
     * Take appropriate action based on state
     */

    switch ( haState )
    {
        /* AMF asks this process to take the standby HA state for the work
           described in the csiDescriptor variable */
        case SA_AMF_HA_ACTIVE:
        {
            /* Typically you would spawn a thread here to initiate active 
               processing of the work. */
            
            if ((csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL )||(csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ONE))
              {
                /* Do not reload the virtual address info for the "TARGET" flag -- the CSI is not filled in.
                   We will use the values that were cached when the "standby" assignment occurred.
                 */
              }
            else /* SA_AMF_CSI_ADD_ONE  */
              {
                GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
              }


            AddRemVirtualAddress("up",&gVirtualIp);

            /* The AMF times the interval between the assignment and acceptance
               of the work (the time interval is configurable).
               So it is important to call this saAmfResponse function ASAP.
             */
            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        /* AMF asks this process to take the standby HA state for the work
           described in the csiDescriptor variable */
        case SA_AMF_HA_STANDBY:
        {
            /* If your standby has ongoing maintenance, you would spawn a thread
               here to do it. */

            /* The AMF times the interval between the assignment and acceptance
               of the work (the time interval is configurable).
               So it is important to call this saAmfResponse function ASAP.
             */
            GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
            AddRemVirtualAddress("down",&gVirtualIp); 
            saAmfResponse(amfHandle, invocation, SA_AIS_OK);  
            break;
        }

        case SA_AMF_HA_QUIESCED:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active or quiescing HA state. The application 
             * must stop work associated with the CSI immediately.
             */
            if ((csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ALL)||(csiDescriptor.csiFlags == SA_AMF_CSI_TARGET_ONE))
            {
                AddRemVirtualAddress("down",&gVirtualIp);           
            }
            else /* SA_AMF_CSI_ADD_ONE */
            {
                VirtualIpAddress temp;
                GetVirtualAddressInfo(&csiDescriptor, &temp);
                AddRemVirtualAddress("down",&temp);
            }

            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_QUIESCING:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active HA state. The application must stop work
             * associated with the CSI gracefully and not accept any new
             * workloads while the work is being terminated.
             */

            /* There are two typical cases for quiescing.  Chooose one!
               CASE 1: Its possible to quiesce rapidly within this thread context */
            if (1)
              {
              /* App code here: Now finish your work and cleanly stop the work*/
            
              /* Call saAmfCSIQuiescingComplete when stopping the work is done */
              saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK);
              }
            else
              {
              /* CASE 2: You can't quiesce within this thread context or quiesce
               rapidly. */

              /* Respond immediately to the quiescing request */
              saAmfResponse(amfHandle, invocation, SA_AIS_OK);

              /* App code here: Signal or spawn a thread to cleanly stop the work*/
              /* When that thread is done, it should call:
                 saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK);
              */
              }

            break;
        }

        default:
        {
            assert(0);
            break;
        }
    }

    return;
}
void clCompAppAMFCSISet(SaInvocationT       invocation,
                        const SaNameT       *compName,
                        SaAmfHAStateT       haState,
                        SaAmfCSIDescriptorT csiDescriptor)
{
    /*
     * Print information about the CSI Set
     */

    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", 
              compName->length, compName->value, mypid);

    clCompAppAMFPrintCSI(csiDescriptor, haState);

    /*
     * Take appropriate action based on state
     */

    switch ( haState )
    {
        case SA_AMF_HA_ACTIVE:
        {
            /*
             * AMF has requested application to take the active HA state 
             * for the CSI.
             */

            if ((csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL)||(csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ONE))
              {
                /* Do not reload the virtual address info for the "TARGET" flag -- the CSI is not filled in.
                   We will use the values that were cached when the "standby" assignment occurred.
                 */
              }
            else /* CL_AMS_CSI_FLAG_ADD_ONE */
              {
                GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
              }

            AddRemVirtualAddress("up",&gVirtualIp);

            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_STANDBY:
        {
            /*
             * AMF has requested application to take the standby HA state 
             * for this CSI.
             */

            GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
            AddRemVirtualAddress("down",&gVirtualIp);  /* Bring it down just in case it is up from a prior run */

            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_QUIESCED:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active or quiescing HA state. The application 
             * must stop work associated with the CSI immediately.
             */
            
            if ((csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL)||(csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ONE))
              {
                AddRemVirtualAddress("down",&gVirtualIp);           
              }
            else /* CL_AMS_CSI_FLAG_ADD_ONE */
              {
                VirtualIpAddress temp;
                GetVirtualAddressInfo(&csiDescriptor, &temp);
                AddRemVirtualAddress("down",&temp);
              }

            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_QUIESCING:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active HA state. The application must stop work
             * associated with the CSI gracefully and not accept any new
             * workloads while the work is being terminated.
             */

            saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        default:
        {
            assert(0);
            break;
        }
    }

    return;
}
void clCompAppAMFCSISet(SaInvocationT       invocation,
                        const SaNameT       *compName,
                        SaAmfHAStateT       haState,
                        SaAmfCSIDescriptorT csiDescriptor)
{
    /*
     * Print information about the CSI Set
     */

    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. CSI Set Received\n", 
              compName->length, compName->value, mypid);

    clCompAppAMFPrintCSI(csiDescriptor, haState);

    /*
     * Take appropriate action based on state
     */

    switch ( haState )
    {
        case SA_AMF_HA_ACTIVE:
        {
            /*
             * AMF has requested application to take the active HA state 
             * for the CSI.
             */

            if (csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL)
              {
                ClRcT rc;
                ClCpmCompCSIRefT csiRef = { 0 };
                ClInt32T i;
                rc = clCpmCompCSIList((SaNameT*)compName, &csiRef);
                if(rc != CL_OK)
                  {
                    clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc);
                  }
                else
                  {
                    for(i = 0; i < csiRef.numCSIs; ++i)
                      {
                        VirtualIpAddress temp;
                        ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i];
                        clprintf(CL_LOG_SEV_INFO,"Comp [%.*s], CSI [%.*s], HA state [%s]",
                                 compName->length,
                                 compName->value, 
                                 pCSI->csiDescriptor.csiName.length,
                                 pCSI->csiDescriptor.csiName.value,
                                 STRING_HA_STATE((ClUint32T)pCSI->haState));

                        GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp);
                        AddRemVirtualAddress("up",&temp);

                      }
                    if(csiRef.pCSIList)
                      clHeapFree(csiRef.pCSIList);
                  }
              }
            else /* CL_AMS_CSI_FLAG_ADD_ONE */
              {
            	GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
                AddRemVirtualAddress("up",&gVirtualIp);
              }

            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_STANDBY:
        {
            /*
             * AMF has requested application to take the standby HA state 
             * for this CSI.
             */

        	GetVirtualAddressInfo(&csiDescriptor, &gVirtualIp);
            AddRemVirtualAddress("down",&gVirtualIp);  /* Bring it down just in case it is up from a prior run */

            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_QUIESCED:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active or quiescing HA state. The application 
             * must stop work associated with the CSI immediately.
             */

              if (csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ONE)
                {
                  AddRemVirtualAddress("down",&gVirtualIp);
                }           
              else if (csiDescriptor.csiFlags == CL_AMS_CSI_FLAG_TARGET_ALL)
              {                
                ClRcT rc;
                ClCpmCompCSIRefT csiRef = { 0 };
                ClInt32T i;
                rc = clCpmCompCSIList((SaNameT*)compName, &csiRef);
                if(rc != CL_OK)
                  {
                    clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc);
                  }
                else
                  {
                    for(i = 0; i < csiRef.numCSIs; ++i)
                      {
                        VirtualIpAddress temp;
                        ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i];

                        clprintf(CL_LOG_SEV_INFO,"Comp [%.*s], CSI [%.*s], HA state [%s]",
                                    compName->length,
                                    compName->value, 
                                    pCSI->csiDescriptor.csiName.length,
                                    pCSI->csiDescriptor.csiName.value,
                                    STRING_HA_STATE((ClUint32T)pCSI->haState));

                        GetVirtualAddressInfoAsp(&pCSI->csiDescriptor, &temp);
                        AddRemVirtualAddress("down",&temp);

                      }
                    if(csiRef.pCSIList)
                      clHeapFree(csiRef.pCSIList);
                  }
              }
              else /* CL_AMS_CSI_FLAG_ADD_ONE */
                {
                  VirtualIpAddress temp;
                  GetVirtualAddressInfo(&csiDescriptor, &temp);
                  AddRemVirtualAddress("down",&temp);
                }

            saAmfResponse(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        case SA_AMF_HA_QUIESCING:
        {
            /*
             * AMF has requested application to quiesce the CSI currently
             * assigned the active HA state. The application must stop work
             * associated with the CSI gracefully and not accept any new
             * workloads while the work is being terminated.
             */

            saAmfCSIQuiescingComplete(amfHandle, invocation, SA_AIS_OK);
            break;
        }

        default:
        {
            assert(0);
            break;
        }
    }

    return;
}