void _CCM_VAC_MappingEngine_OperationToResourceList (TCCM_VAC_MappingEngine *ptMappEngine, 
                                                     ECAL_Operation eOperation,
                                                     TCAL_ResourceList *ptResourceList)
{
    McpU32                      uIndex, uOptListsIndex;
    TCAL_ResourceList           *ptTempList;

    MCP_FUNC_START ("_CCM_VAC_MappingEngine_OperationToResourceList");

    MCP_LOG_INFO (("_CCM_VAC_MappingEngine_OperationToResourceList: requesting resource list for operation %s",
                   _CCM_VAC_DebugOperationStr(eOperation)));

    /* verify object pointer and list pointer */
    MCP_VERIFY_FATAL_NO_RETVAR ((NULL != ptMappEngine), 
                                ("_CCM_VAC_MappingEngine_OperationToResourceList: NULL object!"));
    MCP_VERIFY_FATAL_NO_RETVAR ((NULL != ptResourceList), 
                                ("_CCM_VAC_MappingEngine_OperationToResourceList: NULL resource list!"));

    /* nullify the output resource list */
    ptResourceList->uNumOfResources = 0;

    /* First copy all mandatory resources */
    ptTempList = &(ptMappEngine->tConfig.tOpToResMap[ eOperation ].tMandatoryResources);
    for (uIndex = 0; uIndex < ptTempList->uNumOfResources; uIndex++)
    {
        ptResourceList->eResources[ ptResourceList->uNumOfResources ] = ptTempList->eResources[ uIndex ];
        ptResourceList->uNumOfResources++;
    }

    /* than copy all optional resources lists currently in use */
    for (uOptListsIndex = 0; 
         uOptListsIndex < ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.uNumOfResourceLists;
         uOptListsIndex++)
    {
        /* if this optional resource is in use at the moment */
        if (MCP_TRUE == 
            ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uOptListsIndex ].bIsUsed)
        {
            /* copy the optional resource */
            ptResourceList->eResources[ ptResourceList->uNumOfResources ] =
                ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uOptListsIndex ].eOptionalResource;
            ptResourceList->uNumOfResources++;

            /* set the pointer to the derived resources list */
            ptTempList = 
                &(ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uOptListsIndex ].tDerivedResourcesList);

            /* now copy all derived resources in the list */
            for (uIndex = 0; uIndex < ptTempList->uNumOfResources; uIndex++)
            {
                ptResourceList->eResources[ ptResourceList->uNumOfResources ] = ptTempList->eResources[ uIndex ];
                ptResourceList->uNumOfResources++;
            }
        }
    }

    MCP_FUNC_END ();
}
void _CCM_VAC_MappingEngine_SetOptionalResourcesList (TCCM_VAC_MappingEngine *ptMappEngine,
                                                      ECAL_Operation eOperation,
                                                      TCAL_ResourceList *ptResourceList)
{
    McpU32                      uIndex;

    MCP_FUNC_START ("_CCM_VAC_MappingEngine_SetOptionalResourcesList");

    MCP_LOG_INFO (("_CCM_VAC_MappingEngine_SetOptionalResourcesList: requesting to change optional resources list for "
                   "operation %s", _CCM_VAC_DebugOperationStr(eOperation)));

    /* verify object pointer and list pointer */
    MCP_VERIFY_FATAL_NO_RETVAR ((NULL != ptMappEngine), 
                                ("_CCM_VAC_MappingEngine_SetOptionalResourcesList: NULL object!"));
    MCP_VERIFY_FATAL_NO_RETVAR ((NULL != ptResourceList), 
                                ("_CCM_VAC_MappingEngine_SetOptionalResourcesList: NULL resource list!"));

    /* loop over all optional resources */
    for (uIndex = 0;
         uIndex < ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.uNumOfResourceLists;
         uIndex++)
    {
        /* if this optional resource is include in the new list */
        if (MCP_TRUE ==
            _CCM_VAC_MEIsResourceOnList (ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uIndex ].eOptionalResource,
            ptResourceList))
        {
            /* mark the optional resource as used */
            ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uIndex ].bIsUsed =
                MCP_TRUE;
            MCP_LOG_INFO (("_CCM_VAC_MappingEngine_SetOptionalResourcesList: optional resource %s is "
                           "set to used for operation %s",
                           _CCM_VAC_DebugResourceStr(ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uIndex ].eOptionalResource),
                           _CCM_VAC_DebugOperationStr(eOperation)));
        }
        else
        {
            /* mark the optional resource as unused */
            ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uIndex ].bIsUsed = 
                MCP_FALSE;
            MCP_LOG_INFO (("_CCM_VAC_MappingEngine_SetOptionalResourcesList: optional resource %s is "
                           "set to unused for operation %s",
                           _CCM_VAC_DebugResourceStr(ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uIndex ].eOptionalResource),
                           _CCM_VAC_DebugOperationStr(eOperation)));
        }
    }

    MCP_FUNC_END ();
}
void MCP_DL_LIST_RemoveNode(MCP_DL_LIST_Node* Node)
{
	MCP_FUNC_START("MCP_DL_LIST_RemoveNodeList");
	
	MCP_VERIFY_FATAL_NO_RETVAR((MCP_DL_LIST_IsCircular(Node) == MCP_TRUE), ("MCP_DL_LIST_IsNodeOnList: List is not circular"));
	
	Node->prev->next = Node->next;
	Node->next->prev = Node->prev;
	
	MCP_VERIFY_FATAL_NO_RETVAR((MCP_DL_LIST_IsCircular(Node->prev) == MCP_TRUE), ("MCP_DL_LIST_RemoveNodeList: List is not circular"));

	MCP_DL_LIST_InitializeNode(Node);

	MCP_FUNC_END();
}
/*---------------------------------------------------------------------------
 *            MCP_HciSeq_CreateSequence()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Prepares a HCI sequence to be used
 *
 */
void MCP_HciSeq_CreateSequence (MCP_HciSeq_Context *pContext, 
                                BtHciIfObj *hciIfObj, 
                                McpHalCoreId coreId)
{
    BtHciIfStatus   status;

    MCP_FUNC_START ("MCP_HciSeq_CreateSequence");

    /* nullify variables */
    pContext->uSequenceId = 0;
    pContext->uCommandCount = 0;
    pContext->uCurrentCommandIdx = 0;
    pContext->bPendingCommand = MCP_FALSE;
    /* register a HCI IF client */
    pContext->coreId = coreId;
    if(pContext->coreId == MCP_HAL_CORE_ID_BT)
    {
            status = BT_HCI_IF_RegisterClient(hciIfObj, _MCP_HciSeq_callback, &(pContext->handle));
        MCP_VERIFY_FATAL_NO_RETVAR ((BT_HCI_IF_STATUS_SUCCESS == status),
                                    ("MCP_HciSeq_CreateSequence: BT_HCI_IF_RegisterClient returned status %d",
                                     status));
    }

    MCP_FUNC_END ();
}
/*---------------------------------------------------------------------------
 *            MCP_HciSeq_DestroySequence()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  destroys a HCI sequence that is no longer in use
 *
 */
void MCP_HciSeq_DestroySequence (MCP_HciSeq_Context *pContext)
{
    BtHciIfStatus   status;

    MCP_FUNC_START ("MCP_HciSeq_DestroySequence");

    /* de-register HCI IF client */
    status = BT_HCI_IF_DeregisterClient (&(pContext->handle));
    MCP_VERIFY_FATAL_NO_RETVAR ((BT_HCI_IF_STATUS_SUCCESS == status),
                                ("MCP_HciSeq_DestroySequence: BT_HCI_IF_DeregisterClient returned status %d",
                                 status));

    MCP_FUNC_END ();
}
void _CCM_VAC_MappingEngine_GetOptionalResourcesList (TCCM_VAC_MappingEngine *ptMappEngine,
                                                      ECAL_Operation eOperation,
                                                      TCAL_ResourceList *ptResourceList)
{
    McpU32                      uIndex;

    MCP_FUNC_START ("_CCM_VAC_MappingEngine_GetOptionalResourcesList");

    MCP_LOG_INFO (("_CCM_VAC_MappingEngine_GetOptionalResourcesList: requesting optional resources list for "
                   "operation %s", _CCM_VAC_DebugOperationStr(eOperation)));

    /* verify object pointer and list pointer */
    MCP_VERIFY_FATAL_NO_RETVAR ((NULL != ptMappEngine), 
                                ("_CCM_VAC_MappingEngine_GetOptionalResourcesList: NULL object!"));
    MCP_VERIFY_FATAL_NO_RETVAR ((NULL != ptResourceList), 
                                ("_CCM_VAC_MappingEngine_GetOptionalResourcesList: NULL resource list!"));

    /* nullify the output resource list */
    ptResourceList->uNumOfResources = 0;

    /* loop over all optional resources */
    for (uIndex = 0;
         uIndex < ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.uNumOfResourceLists;
         uIndex++)
    {
        /* if the optional resource is currently in use */
        if (MCP_TRUE == ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uIndex ].bIsUsed)
        {
            /* add it to the list */
            ptResourceList->eResources[ ptResourceList->uNumOfResources ] = 
                ptMappEngine->tConfig.tOpToResMap[ eOperation ].tOptionalResources.tOptionalResourceLists[ uIndex ].eOptionalResource;
            ptResourceList->uNumOfResources++;
        }
    }

    MCP_FUNC_END ();
}
void MCP_DL_LIST_InsertTail(MCP_DL_LIST_Node* head, MCP_DL_LIST_Node* Node)
{
	MCP_FUNC_START("MCP_DL_LIST_InsertTailList");

	/* set the new node's links */
	Node->next = head;
	Node->prev = head->prev;

	/* Make current last node one before last */
	head->prev->next = Node;

	/* Head's prev should point to last element*/
	head->prev = Node;
	
	MCP_VERIFY_FATAL_NO_RETVAR((MCP_DL_LIST_IsNodeConnected(Node) == MCP_TRUE), ("MCP_DL_LIST_InsertTailList: Node is not connected"));

	MCP_FUNC_END();
}
void MCP_DL_LIST_MoveList(MCP_DL_LIST_Node* dest, MCP_DL_LIST_Node* src)
{
	MCP_FUNC_START("MCP_DL_LIST_MoveList");
	
	MCP_VERIFY_FATAL_NO_RETVAR((MCP_DL_LIST_IsCircular(src) == MCP_TRUE), ("MCP_DL_LIST_MoveList: List is not circular"));

	/* New head points at list*/
	dest->next = src->next;
	dest->prev = src->prev;

	/* Detach source head from list */
	src->next->prev = dest;
	src->prev->next = dest;
	
	MCP_DL_LIST_InitializeHead(src);

	MCP_FUNC_END();
}
void MCP_DL_LIST_InsertHead(MCP_DL_LIST_Node* head, MCP_DL_LIST_Node* Node)
{
	MCP_FUNC_START("MCP_DL_LIST_InsertHeadList");
	
	/* set the new node's links */
	Node->next = head->next;
	Node->prev = head;
	
	/* Make current first node second */
	head->next->prev = Node;
	
	/* Head's next should point to first element*/
	head->next = Node;

	MCP_VERIFY_FATAL_NO_RETVAR((MCP_DL_LIST_IsNodeConnected(Node) == MCP_TRUE), ("MCP_DL_LIST_InsertHeadList: Node is not connected"));

	MCP_FUNC_END();
}
void MCP_LoadMngr_Create(BtHciIfObj *hciIfObj)
{
    BtHciIfStatus   status;
    MCP_FUNC_START("MCP_LoadMngr_Create");

    /* Create State Machine */
    MCP_GenSM_Create(&(tDataGenSm),
                     MCP_LM_STATE_MAX_NUM,
                     MCP_LM_EVENT_MAX_NUM,
                     &(tSmMatrix[0][0]),
                     MCP_LM_STATE_UNLOADED,
                     (Mcp_TEnumTString)MCP_LM_EventToString,
                     (Mcp_TEnumTString)MCP_LM_StateToString);

    /* Register a HCI IF client */
    status = BT_HCI_IF_RegisterClient(hciIfObj, MCP_LoadMngr_Hci_Cmds_callback, &(handle));
    MCP_VERIFY_FATAL_NO_RETVAR ((BT_HCI_IF_STATUS_SUCCESS == status),
                                ("MCP_LoadMngr_Create: BT_HCI_IF_RegisterClient returned status %d",
                                 status));

    MCP_FUNC_END();
}
MCP_STATIC void MCP_LM_Load (void *pUserData)
{
    McpBtsSpStatus status;
    McpBtsSpScriptLocation tScriptLocation;
    McpBool memInitScriptFound;
    McpUtf8 scriptFullFileName[MCP_HAL_CONFIG_FS_MAX_PATH_LEN_CHARS *
                               MCP_HAL_CONFIG_MAX_BYTES_IN_UTF8_CHAR];

    MCP_FUNC_START ("MCP_LM_Load");

    MCP_UNUSED_PARAMETER (pUserData);

    /* First try to load the script from FS */
    tScriptLocation.locationType = MCP_BTS_SP_SCRIPT_LOCATION_FS;
    MCP_StrCpyUtf8(scriptFullFileName, (const McpUtf8 *)pScriptLocation);
    MCP_StrCatUtf8(scriptFullFileName, (const McpUtf8 *)pScriptName);
    tScriptLocation.locationData.fullFileName = scriptFullFileName;

    /* Execute the requested script*/
    status = MCP_BTS_SP_ExecuteScript (&tScriptLocation, &tExcuteCallbacks, &context);

    if (status == MCP_BTS_SP_STATUS_PENDING)
    {
        /* Update the State Machine status */
        iLoadSmstatus = MCP_HAL_STATUS_PENDING;
    }
    else if (status == MCP_BTS_SP_STATUS_SUCCESS)
    {
        /* Update the State Machine status */
        iLoadSmstatus = MCP_HAL_STATUS_SUCCESS;    
    }
    else if (MCP_BTS_SP_STATUS_FILE_NOT_FOUND == status)
    {
        /* FS Script Not Found - Use default hard-coded memory script instead */
        tScriptLocation.locationType = MCP_BTS_SP_SCRIPT_LOCATION_MEMORY;

        /* Check if memory has a script for this version and load its parameters if found */
        memInitScriptFound =  MCP_RomScriptsGetMemInitScriptData(
                                    pScriptName, 
                                    &tScriptLocation.locationData.memoryData.size,
                                    (const McpU8**)&tScriptLocation.locationData.memoryData.address);

        /* verify the script was found in memory */
        MCP_VERIFY_FATAL_NO_RETVAR ((memInitScriptFound == MCP_TRUE),
                          ("MCP_LM_Load: can't find script %s on FS and memory", pScriptName));

        /* execute the memory script */
        status = MCP_BTS_SP_ExecuteScript(&tScriptLocation, &tExcuteCallbacks, &context);

        if (status == MCP_BTS_SP_STATUS_PENDING)
        {
            iLoadSmstatus = MCP_HAL_STATUS_PENDING;
        }
        else if (status == MCP_BTS_SP_STATUS_SUCCESS)
        {
            iLoadSmstatus = MCP_HAL_STATUS_SUCCESS;
        }
        else
        {
            iLoadSmstatus = MCP_HAL_STATUS_FAILED;
        }
    }
    else
    {
        /* Update the State Machine status */
        iLoadSmstatus = MCP_HAL_STATUS_FAILED;
    }

    MCP_FUNC_END();
}
void _CCM_VAC_AllocationEngine_Release (TCCM_VAC_AllocationEngine *ptAllocEngine,
                                        ECAL_Resource eResource,
                                        ECAL_Operation eOperation)
{
    MCP_FUNC_START ("_CCM_VAC_AllocationEngine_Release");

    MCP_LOG_INFO (("_CCM_VAC_AllocationEngine_Release: operation %s releasing resource %s",
                   _CCM_VAC_DebugOperationStr(eOperation),
                   _CCM_VAC_DebugResourceStr (eResource)));

    /* verify object pointer, resource availability, and resource allocation */
    MCP_VERIFY_FATAL_NO_RETVAR ((NULL != ptAllocEngine),
                                ("_CCM_VAC_AllocationEngine_Release: NULL object!"));
    MCP_VERIFY_ERR_NO_RETVAR ((MCP_TRUE == ptAllocEngine->tResources[ eResource ].bAvailable),
                              ("_CCM_VAC_AllocationEngine_Release: attempting to release resource %s "
                               "which is unavailable, by operation %s",
                               _CCM_VAC_DebugResourceStr (eResource),
                               _CCM_VAC_DebugOperationStr (eOperation)));
    MCP_VERIFY_ERR_NO_RETVAR ((0 < ptAllocEngine->tResources[ eResource ].uNumberOfOwners),
                              ("_CCM_VAC_AllocationEngine_Release: resource %s is not allocated!",
                               _CCM_VAC_DebugResourceStr (eResource)));
    
    /* if the resource is allocated by only one operation */
    if (1 == ptAllocEngine->tResources[ eResource ].uNumberOfOwners)
    {
        /* verify resource owner is the requesting operation */
        MCP_VERIFY_ERR_NO_RETVAR ((ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 0 ] == eOperation),
                                  ("_CCM_VAC_AllocationEngine_Release: operation %s requesting to release "
                                   "resource %s, which is allocated to operation %s!",
                                   _CCM_VAC_DebugOperationStr(eOperation),
                                   _CCM_VAC_DebugResourceStr (eResource),
                                   _CCM_VAC_DebugOperationStr(ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 0 ])));

        /* release the resource */
        ptAllocEngine->tResources[ eResource ].uNumberOfOwners--;
    }
    /* the resource is mutually allocated by two operations */
    else
    {
        /* the requesting operation is in first place */
        if (ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 0 ] == eOperation)
        {
            /* move the operation in second place to first place */
            ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 0 ] = 
                ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 1 ];
            /* reduce number of owners */
            ptAllocEngine->tResources[ eResource ].uNumberOfOwners--;
        }
        /* the requesting operation is in second place */
        else if (ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 1 ] == eOperation)
        {
            /* simply reduce number of owners */
            ptAllocEngine->tResources[ eResource ].uNumberOfOwners--;
        }
        else
        {
            MCP_ERR_NO_RETVAR (("_CCM_VAC_AllocationEngine_Release: resource %s ia allocated to "
                                "operations %s and %s!",
                                _CCM_VAC_DebugOperationStr(ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 0 ]),
                                _CCM_VAC_DebugOperationStr(ptAllocEngine->tResources[ eResource ].eCurrentOwners[ 1 ])));
        }
    }

    MCP_FUNC_END ();
}