/**************************************************************************//**
  \brief Handles application command from appCmdQueue.

  \param  None.

  \return None.
******************************************************************************/
void appCmdHandler(void)
{
    AppCommand_t *currentCommand = appGetCommandToProcess();

    if (currentCommand)
    {
        bool deleteCmd = true;
        AppCommandDescriptor_t cmdDesc;

        if (appGetCmdDescriptor(&cmdDesc, currentCommand->dongleCommandId))
        {
            deleteCmd = cmdDesc.serviceVector(currentCommand);
        }

        if (deleteCmd)
        {
            putQueueElem(&appFreeCmdQueue, deleteHeadQueueElem(&appBusyCmdQueue));
        }
        else
        {
            putQueueElem(&appBusyCmdQueue, deleteHeadQueueElem(&appBusyCmdQueue));
        }

        appPostCmdHandlerTask();
    }
}
/**************************************************************************//**
  \brief Inserts new element into the command queue.

  \param[in,out] pCommandPtr - pointer to pointer to AppCommand_t. On the output
                               if function returns true *pCommandPtr will refer
                               to allocated cell.

  \return true if insertion was successful, false otherwise.
******************************************************************************/
bool appCreateCommand(AppCommand_t **pCommandPtr)
{
    AppCmdQueueElement_t *appCmdQueueElement = NULL;
    QueueElement_t *freeElement = NULL;
    bool result = false;

    assert(pCommandPtr, CMDQUEUEINSERTASSERT_0);

    freeElement = getQueueElem(&appFreeCmdQueue);

    if (freeElement)
    {
        putQueueElem(&appBusyCmdQueue, deleteHeadQueueElem(&appFreeCmdQueue));
        appCmdQueueElement = GET_STRUCT_BY_FIELD_POINTER(AppCmdQueueElement_t,
                             next,
                             freeElement);

        if (*pCommandPtr)
        {
            memcpy(&appCmdQueueElement->command, *pCommandPtr, sizeof(AppCommand_t));
        }

        *pCommandPtr = &appCmdQueueElement->command;

        result = true;
    }

    appPostCmdHandlerTask();
    return result;
}
/**************************************************************************//**
  \brief Initializes command handler.

  \param  None.

  \return None.
******************************************************************************/
void appInitCmdHandler(void)
{
    resetQueue(&appBusyCmdQueue);
    resetQueue(&appFreeCmdQueue);

    for (uint8_t i = 0; i < ARRAY_SIZE(appCmdBuffers); i++)
    {
        putQueueElem(&appFreeCmdQueue, &appCmdBuffers[i].next);
    }
}
/******************************************************************************
  Encryption commands handler.
  Parameters:
    request - pointer to request parameters structure.
  Returns:
    none
******************************************************************************/
void HAL_SmEncryptReq(HAL_SmEncryptReq_t *request)
{
  putQueueElem(&halSmRequestQueue, request);
  halPostTask3(HAL_SM_REQ);
}