summaryrefslogtreecommitdiffstats
path: root/ucs2-lib/src/ucs_epm.c
blob: adc5aab241f1bb377871a94a3f136d381120753f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
###########################################################################
# Copyright 2015, 2016, 2017 IoT.bzh
#
# author: Fulup Ar Foll <fulup@iot.bzh>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###########################################################################


# Add target to project dependency list
PROJECT_TARGET_ADD(hal-intel-hda)

    # Define project Targets
    ADD_LIBRARY(hal-intel-hda MODULE IntelHdaHAL.c)

    # Binder exposes a unique public entry point
    SET_TARGET_PROPERTIES(hal-intel-hda PROPERTIES
	PREFIX "afb-"
        LABELS "BINDING"
	LINK_FLAGS  ${BINDINGS_LINK_FLAG}
        OUTPUT_NAME ${TARGET_NAME}
    )

    # Library dependencies (include updates automatically)
    TARGET_LINK_LIBRARIES(hal-intel-hda 
        hal-interface
        audio-interface
    )

    # installation directory
    INSTALL(TARGETS hal-intel-hda
        LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR})
358' href='#n358'>358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
/*------------------------------------------------------------------------------------------------*/
/* UNICENS V2.1.0-3491                                                                            */
/* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG.                              */
/*                                                                                                */
/* This program is free software: you can redistribute it and/or modify                           */
/* it under the terms of the GNU General Public License as published by                           */
/* the Free Software Foundation, either version 2 of the License, or                              */
/* (at your option) any later version.                                                            */
/*                                                                                                */
/* This program is distributed in the hope that it will be useful,                                */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of                                 */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                  */
/* GNU General Public License for more details.                                                   */
/*                                                                                                */
/* You should have received a copy of the GNU General Public License                              */
/* along with this program.  If not, see <http://www.gnu.org/licenses/>.                          */
/*                                                                                                */
/* You may also obtain this software under a propriety license from Microchip.                    */
/* Please contact Microchip for further information.                                              */
/*------------------------------------------------------------------------------------------------*/

/*!
 * \file
 * \brief Implementation of the EndPoint Management.
 *
 * \cond UCS_INTERNAL_DOC
 * \addtogroup G_EPM
 * @{
 */

/*------------------------------------------------------------------------------------------------*/
/* Includes                                                                                       */
/*------------------------------------------------------------------------------------------------*/
#include "ucs_epm.h"
#include "ucs_misc.h"

/*------------------------------------------------------------------------------------------------*/
/* Internal prototypes                                                                            */
/*------------------------------------------------------------------------------------------------*/
static void Epm_XrmReportCb (uint16_t node_address, uint16_t connection_label, Ucs_Xrm_Result_t result, void * user_arg);
static bool Epm_RsmReportSyncLost (Fac_Inst_t inst_type, void * inst_ptr, void *ud_ptr);

/*------------------------------------------------------------------------------------------------*/
/* Implementation of class CEndpointManagement                                                     */
/*------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
/* Initialization Methods                                                                         */
/*------------------------------------------------------------------------------------------------*/
/*! \brief Constructor of the Remote Sync Manager class.
 *  \param self        Instance pointer
 *  \param init_ptr    init data_ptr
 */
void Epm_Ctor(CEndpointManagement *self, Epm_InitData_t *init_ptr)
{
    MISC_MEM_SET(self, 0, sizeof(CEndpointManagement));

    /* Init all instances */
    self->fac_ptr = init_ptr->fac_ptr;
    self->base_ptr = init_ptr->base_ptr;
    self->res_debugging_fptr = init_ptr->res_debugging_fptr;
    self->check_unmute_fptr  = init_ptr->check_unmute_fptr;
}

/*! \brief Initializes the internal information of the given endpoint object.
 *
 *  Initialization is performed only if the magic number is not set.
 *
 *  \param self      Instance pointer
 *  \param ep_ptr    Reference to the endpoint to be looked for
 */
void Epm_InitInternalInfos(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr)
{
    if ((self != NULL) && (ep_ptr != NULL))
    {
        if (ep_ptr->internal_infos.magic_number != (uint32_t)0x0BADC0DE)
        {
            MISC_MEM_SET(&ep_ptr->internal_infos, 0, sizeof(Ucs_Rm_EndPointInt_t));

            ep_ptr->internal_infos.magic_number = (uint32_t)0x0BADC0DE;
            Sub_Ctor(&ep_ptr->internal_infos.subject_obj, self->base_ptr->ucs_user_ptr);
            /* Set the EndpointManagement instance */
            ep_ptr->internal_infos.epm_inst = (Epm_Inst_t *)(void *)self;
        }
    }
}

/*! \brief Clears the internal information of the given endpoint object.
 *
 * Resetting the magic number of the given endpoint will enforce Its Re-Initialization.
 *
 *  \param self      Instance pointer
 *  \param ep_ptr    Reference to the endpoint to be cleared.
 */
void Epm_ClearIntInfos(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr)
{
    MISC_UNUSED (self);
    if (ep_ptr != NULL)
    {
        ep_ptr->internal_infos.magic_number = 0x0U;
    }
}

/*------------------------------------------------------------------------------------------------*/
/* Service                                                                                        */
/*------------------------------------------------------------------------------------------------*/
/*! \brief Add an observer to the Endpoint's subject.
 *  \param ep_ptr     Reference to the endpoint instance
 *  \param obs_ptr    Reference to the observer object
 */
void Epm_AddObserver(Ucs_Rm_EndPoint_t * ep_ptr, CObserver * obs_ptr)
{
    Sub_Ret_t ret_val = SUB_UNKNOWN_OBSERVER;

    ret_val = Sub_AddObserver(&ep_ptr->internal_infos.subject_obj, obs_ptr);
    if (ret_val == SUB_OK)
    {
        if ((ep_ptr != NULL) && (ep_ptr->endpoint_type == UCS_RM_EP_SOURCE))
        {
            if ((ep_ptr->internal_infos.endpoint_state == UCS_RM_EP_BUILT) && (ep_ptr->internal_infos.reference_cnt > 0U))
            {
                ep_ptr->internal_infos.reference_cnt++;
            }
        }
    }
}

/*! \brief Removes an observer registered by Epm_AddObserver
 *  \param ep_ptr     Reference to the endpoint instance
 *  \param obs_ptr    Reference to the observer object
 */
void Epm_DelObserver(Ucs_Rm_EndPoint_t * ep_ptr, CObserver * obs_ptr)
{
    (void)Sub_RemoveObserver(&ep_ptr->internal_infos.subject_obj, obs_ptr);  
}

/*! \brief Processes the construction of the given endpoint
 *  \param self               Instance pointer
 *  \param ep_ptr             reference to an endpoint 
 *  \return Possible return values are
 *          - \c UCS_RET_ERR_API_LOCKED the API is locked. Endpoint is currently being processed.
 *          - \c UCS_RET_SUCCESS the build process was set successfully
 *          - \c UCS_RET_ERR_PARAM NULL pointer detected in the parameter list
 *          - \c UCS_RET_ERR_ALREADY_SET the endpoint has already been set
 */
Ucs_Return_t Epm_SetBuildProcess(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr)
{
    Ucs_Return_t result = UCS_RET_ERR_PARAM;

    if ((self != NULL)  && (ep_ptr != NULL))
    {
        /* Process Endpoint construction by XRM */
        result = Xrm_Process(Fac_GetXrm(self->fac_ptr, ep_ptr->node_obj_ptr->signature_ptr->node_address, &Epm_XrmResDebugCb, self->check_unmute_fptr),
                            ep_ptr->jobs_list_ptr, ep_ptr->internal_infos.connection_label, 
                            (void *)ep_ptr, &Epm_XrmReportCb);
        if (result == UCS_RET_SUCCESS)
        {
            if (ep_ptr->internal_infos.endpoint_state != UCS_RM_EP_BUILT)
            {
                ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_XRMPROCESSING;
                TR_INFO((self->base_ptr->ucs_user_ptr, "[EPM]", "XRM has been ordered to create following Endpoint: %X", 1U, ep_ptr));
            }
            else
            {
                TR_INFO((self->base_ptr->ucs_user_ptr, "[EPM]", "Following Endpoint {%X} has already been built", 1U, ep_ptr));
            }
        }
        else if (result == UCS_RET_ERR_ALREADY_SET)
        {
            if (ep_ptr->internal_infos.endpoint_state == UCS_RM_EP_IDLE)
            {
                ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_BUILT;          
                TR_INFO((self->base_ptr->ucs_user_ptr, "[EPM]", "Following Endpoint {%X} has already been built", 1U, ep_ptr));
            }
        }
        else if (result == UCS_RET_ERR_NOT_AVAILABLE)
        {
            /* Set the internal error */
            ep_ptr->internal_infos.endpoint_state  = UCS_RM_EP_IDLE;
            ep_ptr->internal_infos.xrm_result.code = UCS_XRM_RES_ERR_BUILD;
            ep_ptr->internal_infos.xrm_result.details.result_type = UCS_XRM_RESULT_TYPE_INT;
            ep_ptr->internal_infos.xrm_result.details.int_result  = result;
        }
    }

    return result;
}

/*! \brief Processes the destruction of the given endpoint
 *  \param self               Instance pointer
 *  \param ep_ptr             reference to an endpoint 
 *  \return Possible return values are
 *          - \c UCS_RET_ERR_API_LOCKED the API is locked. Endpoint is currently being processed.
 *          - \c UCS_RET_SUCCESS the build process was set successfully
 *          - \c UCS_RET_ERR_PARAM At least one parameter is not correct, either NULL pointer in the param list or reference_cnt of the endpoint is NULL.
 *          - \c UCS_RET_ERR_ALREADY_SET the endpoint has already been set
 *          - \c UCS_RET_ERR_NOT_AVAILABLE the endpoint cannot be destroyed since its reference_cnt is greater than 1, i.e. it's in use.
 *          - \c UCS_RET_ERR_INVALID_SHADOW the endpoint cannot be destroyed since its reference_cnt is greater than 1, i.e. it's in use.
 */
Ucs_Return_t Epm_SetDestroyProcess(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr)
{
    Ucs_Return_t result = UCS_RET_ERR_PARAM;
    bool can_be_destroyed = true;

    if ((self != NULL)  && (ep_ptr != NULL) )
    {
        if (UCS_RM_EP_SOURCE == ep_ptr->endpoint_type)
        {
            if (ep_ptr->internal_infos.reference_cnt == 0U)
            {
                can_be_destroyed = false;
                result = UCS_RET_ERR_PARAM;
            }
            else if (ep_ptr->internal_infos.reference_cnt > 1U)
            {
                ep_ptr->internal_infos.reference_cnt--;
                can_be_destroyed = false;
                result = UCS_RET_ERR_INVALID_SHADOW;
            }
        }

        if (can_be_destroyed)
        {
            result = Xrm_Destroy(Fac_GetXrmByJobList(self->fac_ptr, ep_ptr->jobs_list_ptr), ep_ptr->jobs_list_ptr);
            if (result == UCS_RET_SUCCESS)
            {
                ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_XRMPROCESSING;
                TR_INFO((self->base_ptr->ucs_user_ptr, "[EPM]", "XRM has been ordered to destroy following Endpoint {%X}", 1U, ep_ptr));
            }
            else if (result == UCS_RET_ERR_ALREADY_SET)
            {
                if (ep_ptr->internal_infos.endpoint_state == UCS_RM_EP_BUILT)
                {
                    ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_IDLE;          
                    TR_INFO((self->base_ptr->ucs_user_ptr, "[EPM]", "Following Endpoint {%X} has already been destroyed", 1U, ep_ptr));
                }
            }
            else if (result == UCS_RET_ERR_NOT_AVAILABLE)
            {
                if (ep_ptr->internal_infos.endpoint_state == UCS_RM_EP_BUILT)
                {
                    ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_IDLE;
                    TR_INFO((self->base_ptr->ucs_user_ptr, "[EPM]", "Following Endpoint {%X} has already been destroyed", 1U, ep_ptr));
                }
            }
        }
    }

    return result;
}

/*! \brief Returns the state (idle, processing or built) of the given endpoint.
 *  \param self   Instance pointer.
 *  \param ep_ptr Reference to the endpoint to be looked for
 *  \return state of the endpoint.
 */
Ucs_Rm_EndPointState_t Epm_GetState(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr)
{
    MISC_UNUSED (self);

    return (ep_ptr != NULL) ? ep_ptr->internal_infos.endpoint_state:UCS_RM_EP_IDLE;
}

/*! \brief Forces EPM to reset the state of this endpoint.
 *  \param self      Instance pointer.
 *  \param ep_ptr    Reference to the endpoint to be looked for.
 */
void Epm_ResetState(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr)
{
    MISC_UNUSED (self);

    if (ep_ptr != NULL)
    {
        ep_ptr->internal_infos.endpoint_state  = UCS_RM_EP_IDLE;
        ep_ptr->internal_infos.xrm_result.code = UCS_XRM_RES_UNKNOWN;
    }
}

/*! \brief Sets the connection label of the given endpoint.
 *  \param self       Instance pointer.
 *  \param ep_ptr     Reference to the endpoint to be looked for
 *  \param conn_label connection label to be set
 */
void Epm_SetConnectionLabel(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr, uint16_t conn_label)
{
    MISC_UNUSED (self);

    if (ep_ptr != NULL)
    {
        ep_ptr->internal_infos.connection_label = conn_label;
    }
}

/*! \brief Returns the connection label of the given endpoint.
 *  \param self   Instance pointer.
 *  \param ep_ptr Reference to the endpoint to be looked for
 *  \return connection label of the endpoint.
 */
uint16_t Epm_GetConnectionLabel(CEndpointManagement * self, Ucs_Rm_EndPoint_t * ep_ptr)
{
    MISC_UNUSED (self);

    return (ep_ptr != NULL) ? ep_ptr->internal_infos.connection_label:0U;
}

/*! \brief  This function must be called when a device get invalid. 
 *  \param  self                Reference to the MNS instance.
 *  \param  destination_address MOST device address of the target.
 */
void Epm_ReportInvalidDevice(CEndpointManagement *self, uint16_t destination_address)
{
    if (MSG_ADDR_INIC != destination_address)
    {
        CRemoteSyncManagement * rsm_inst = Fac_FindRsm(self->fac_ptr, destination_address);
        if (NULL != rsm_inst)
        {
            Rsm_ReportSyncLost(rsm_inst);
        }
    }
}

/*! \brief Whenever this function has been called, the EndpointManager has to inform his sub-modules that a shutdown occurred. 
 *         This function forwards the Network "NotAvailable" information
 *  \param self   Instance pointer.
 */
void Epm_ReportShutDown(CEndpointManagement * self)
{
    Fac_Foreach(self->fac_ptr, FAC_INST_RSM, &Epm_RsmReportSyncLost, NULL);
}

/*! \brief  Function signature used for monitoring the XRM resources.
 *  \param  resource_type       The XRM resource type to be looked for
 *  \param  resource_ptr        Reference to the resource to be looked for
 *  \param  resource_infos      Resource information
 *  \param  endpoint_inst_ptr   Reference to the endpoint object that encapsulates the given resource.
 *  \param  user_ptr            User reference provided in \ref Ucs_InitData_t "Ucs_InitData_t::user_ptr"
 */
void Epm_XrmResDebugCb (Ucs_Xrm_ResourceType_t resource_type, Ucs_Xrm_ResObject_t *resource_ptr, 
                               Ucs_Xrm_ResourceInfos_t resource_infos, void *endpoint_inst_ptr, void *user_ptr)
{
    Ucs_Rm_EndPoint_t * ep_ptr = (Ucs_Rm_EndPoint_t *)endpoint_inst_ptr;
    if (ep_ptr != NULL)
    {
        CEndpointManagement * self = (CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst;
        if (self->res_debugging_fptr != NULL)
        {
            self->res_debugging_fptr(resource_type, resource_ptr, resource_infos, ep_ptr, user_ptr);
        }
    }
}

/*------------------------------------------------------------------------------------------------*/
/* Private Methods                                                                                */
/*------------------------------------------------------------------------------------------------*/
/*! \brief Reports "SyncLost" to the RSM instance returned.
 *  \param inst_type  The instance type to be looked for.
 *  \param inst_ptr   Reference to the instance to be looked for.
 *  \param ud_ptr     Reference to the user data.
 *  \return false in order to retrieve the next instance of the given type, otherwise false.
 */
static bool Epm_RsmReportSyncLost(Fac_Inst_t inst_type, void * inst_ptr, void *ud_ptr)
{
    bool ret_val = false;
    MISC_UNUSED(ud_ptr);

    switch (inst_type)
    {
        case FAC_INST_RSM:
            Rsm_ReportSyncLost((CRemoteSyncManagement *)inst_ptr);
            break;

        default:
            ret_val = true;
            break;
    }

    return ret_val;
}

/*------------------------------------------------------------------------------------------------*/
/* Callback Functions                                                                             */
/*------------------------------------------------------------------------------------------------*/
/*! \brief  XRM report callback function.
 *  \param  node_address        The node address from which the results come 
 *  \param  connection_label    Returned MOST network connection label
 *  \param  result              Result of the job
 *  \param  user_arg            Reference to the user argument
 */
static void Epm_XrmReportCb(uint16_t node_address, uint16_t connection_label, Ucs_Xrm_Result_t result, void * user_arg)
{
    Ucs_Rm_EndPoint_t * ep_ptr = (Ucs_Rm_EndPoint_t *)user_arg;
    uint8_t handle_not_found   = 0x32U;
    uint8_t error_id = 2U;

    MISC_UNUSED (node_address);

    if (ep_ptr != NULL)
    {
        ep_ptr->internal_infos.xrm_result = result;
        switch (result.code)
        {
        case UCS_XRM_RES_SUCCESS_BUILD:
            ep_ptr->internal_infos.connection_label = connection_label;
            ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_BUILT;
            if (ep_ptr->endpoint_type == UCS_RM_EP_SOURCE)
            {
                ep_ptr->internal_infos.reference_cnt++;
            }            
            TR_INFO((((CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst)->base_ptr->ucs_user_ptr, "[EPM]", "Following Endpoint {%X} has been successfully built", 1U, ep_ptr));
            break;

        case UCS_XRM_RES_SUCCESS_DESTROY:
            ep_ptr->internal_infos.connection_label = 0xFFFFU;
            ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_IDLE;
            if (ep_ptr->endpoint_type == UCS_RM_EP_SOURCE)
            {
                if (ep_ptr->internal_infos.reference_cnt > 0U)
                {
                    ep_ptr->internal_infos.reference_cnt--;
                }
            }
            TR_INFO((((CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst)->base_ptr->ucs_user_ptr, "[EPM]", "Following Endpoint {%X} has been successfully destroyed", 1U, ep_ptr));
            break;

        case UCS_XRM_RES_RC_AUTO_DESTROYED:
            TR_ERROR((((CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst)->base_ptr->ucs_user_ptr, "[EPM]", "Following Endpoint {%X} has been auto destroyed.", 1U, ep_ptr));
            ep_ptr->internal_infos.connection_label = 0xFFFFU;
            ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_IDLE;
            if (ep_ptr->endpoint_type == UCS_RM_EP_SOURCE)
            {
                ep_ptr->internal_infos.reference_cnt = 0U;
            }
            if(Sub_GetNumObservers(&ep_ptr->internal_infos.subject_obj) > 0U)
            {
                Sub_Notify(&ep_ptr->internal_infos.subject_obj, (void *)ep_ptr);
            }
            break;

        case UCS_XRM_RES_ERR_CONFIG:
        case UCS_XRM_RES_ERR_SYNC:
        case UCS_XRM_RES_ERR_BUILD:
            ep_ptr->internal_infos.connection_label = 0xFFFFU;
            ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_IDLE;
            TR_ERROR((((CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst)->base_ptr->ucs_user_ptr, "[EPM]", "Building endpoint {%X} failed. Error_Code: 0x%02X", 2U, ep_ptr, result.code));
            break;

        case UCS_XRM_RES_ERR_DESTROY:
            ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_IDLE;
            if (ep_ptr->internal_infos.xrm_result.details.result_type == UCS_XRM_RESULT_TYPE_TGT)
            {
                if ((ep_ptr->internal_infos.xrm_result.details.inic_result.code == UCS_RES_ERR_CONFIGURATION) &&
                    (ep_ptr->internal_infos.xrm_result.details.inic_result.info_ptr != NULL) && 
                    (ep_ptr->internal_infos.xrm_result.details.inic_result.info_size > 2U))
                {
                    if (ep_ptr->internal_infos.xrm_result.details.inic_result.info_ptr[error_id] == handle_not_found)
                    {
                        ep_ptr->internal_infos.xrm_result.code = UCS_XRM_RES_SUCCESS_DESTROY;
                    }
                }
            }
            if (ep_ptr->endpoint_type == UCS_RM_EP_SOURCE)
            {
                ep_ptr->internal_infos.reference_cnt = 0U;
            }
            TR_ERROR((((CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst)->base_ptr->ucs_user_ptr, "[EPM]", "Destroying endpoint {%X} failed. Error_Code: 0x%02X", 2U, ep_ptr, result.code));
            break;

        case UCS_XRM_RES_ERR_INV_LIST:
            TR_ERROR((((CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst)->base_ptr->ucs_user_ptr, "[EPM]", "Request of invalid lists on endpoint {%X} failed.", 1U, ep_ptr));
            if (ep_ptr->internal_infos.endpoint_state == UCS_RM_EP_BUILT)
            {
                ep_ptr->internal_infos.connection_label = 0xFFFFU;
                ep_ptr->internal_infos.endpoint_state = UCS_RM_EP_IDLE;
                if(Sub_GetNumObservers(&ep_ptr->internal_infos.subject_obj) > 0U)
                {
                    Sub_Notify(&ep_ptr->internal_infos.subject_obj, (void *)ep_ptr);
                }
            }
            break;

        default:
            TR_ERROR((((CEndpointManagement *)(void *)ep_ptr->internal_infos.epm_inst)->base_ptr->ucs_user_ptr, "[EPM]", "Processing endpoint {%X} failed. Unknown Error_Code: 0x%02X", 2U, ep_ptr, result.code));
            break;
        }
    }
}

/*!
 * @}
 * \endcond
 */

/*------------------------------------------------------------------------------------------------*/
/* End of file                                                                                    */
/*------------------------------------------------------------------------------------------------*/