/*****************************************************************************
 *                            Intel Proprietary
 *
 * Copyright (c) 1998-2002 By Intel Corporation.  All rights reserved.  
 * No part of this program or publication may be reproduced, transmitted,
 * transcribed, stored in a retrieval system, or translated into any language
 * or computer language in any form or by any means, electronic, mechanical,
 * magnetic, optical, chemical, manual, or otherwise, without the prior
 * written permission of:
 *                        Intel Corporation
 *                        2200 Mission College Blvd.
 *                        Santa Clara, CA  95052-8119
 *****************************************************************************/

/**
 *****************************************************************************
 * @ingroup LlcSnapEncap
 *
 * File:  ix_cc_llc_snap_encap_msg_helpers.c
 *
 * @description
 *      This file defines the message helper API exported by the LLC Snap
 *      Encapsulation Core Component.
 *
 *****************************************************************************/

/*****************************************************************************
 *
 * Contents:
 *        Definitions of following exported data:
 *
 *        Definitions of following exported functions:
 *            ix_cc_llc_snap_encap_async_add_next_hop
 *            ix_cc_llc_snap_encap_async_delete_next_hop
 *
 *        Definitions of following local data:
 *
 *        Definitions of following local functions:
 *            _ix_cc_llc_snap_encap_cb_add_next_hop
 *            _ix_cc_llc_snap_encap_cb_delete_next_hop
 *
 *****************************************************************************/


/*
 * User defined include files
 */
#include "ix_cc_llc_snap_encap.h"
#include "ix_cc_llc_snap_encap_private.h"
#if (_IX_OS_TYPE_ == _IX_OS_LINUX_KERNEL_)
#include "ix_cc_msup.h"
#endif

/**
 ****************************************************************************
 * @ingroup LlcSnapEncap
 * Add a new Next Hop entry to the table
 * @description
 *    This message helper function builds and sends an "Add Next Hop"
 *    message for the LLC Snap Encapsulation core component. All the user
 *    provided data are sent along to fill the entry in the Next Hop table.
 *
 * @param nextHop - IN: Next Hop ID
 * @param vpi - IN: outgoing VPI for the packet
 * @param vci - IN: outgoing VCI for the packet
 * @param vcq - IN: VCQ number for the packet
 * @param dSap - IN: LLC header: DSAP field
 * @param sSap - IN: LLC header: SSAP field
 * @param ctrl - IN: LLC header: Ctrl field
 * @param oui - IN: SNAP header: Organizationally Unique Identifier (OUI) field
 * @param pid - IN: SNAP header: Protocol Identifier (PID) field   
 * @param pUserCallback - IN: pointer to the user callback function
 * @param pUserContext - IN: pointer to the user provided context data (opaque
 *                       for the LLC Snap Encap CC).
 *
 * @retval IX_SUCCESS - message was successfully built and sent 
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM - invalid pointer
 *                                                          in input parameters
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_MSG_LIBRARY - failed sending a message 
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED - Core Component not
 *                                                      initialized yet
 *
 *****************************************************************************/
ix_error
ix_cc_llc_snap_encap_async_add_next_hop(
    ix_uint16 nextHop,
    ix_uint8 encapType,
    ix_uint16 vpi,
    ix_uint16 vci,
    ix_uint16 vcq,
    ix_uint8 dSap,
    ix_uint8 sSap,
    ix_uint8 ctrl,
    ix_uint32 oui,
    ix_uint16 pid,
    ix_cc_llc_snap_encap_cb_add_next_hop pCallback,
    void *pUserContext)
{
    ix_cc_llc_snap_encap_add_next_hop_data_t addNextHopData;
    ix_cc_llc_snap_encap_add_next_hop_callback_data_t* pCbContext;
    ix_error err = IX_SUCCESS;

    /* check if CC is initialized yet */
    if ((pLlcSnapEncapContext == NULL) ||
        (pLlcSnapEncapContext->initialized != TRUE))
    {
        /* Core Component not initialized */
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED,
        ("LLC Snap Encap Msg helper: CC not initialized yet"));
    }

    /* check parameters' consistency */
    if (pCallback == NULL)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM,
        ("LLC Snap Encap Msg helper: Invalid pointer_pCallback"));
    }

    pCbContext = (ix_cc_llc_snap_encap_add_next_hop_callback_data_t*) \
       ix_ossl_malloc(sizeof(ix_cc_llc_snap_encap_add_next_hop_callback_data_t));
    
    if (pCbContext == NULL)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_MSG_LIBRARY,
        ("LLC Snap Encap Msg helper: No memory for context"));
    }

    /* prepare data to be sent in a message */
    addNextHopData.nextHop   = nextHop;
    addNextHopData.encapType = encapType;
    addNextHopData.vpi       = vpi;
    addNextHopData.vci       = vci;
    addNextHopData.vcq       = vcq;
    addNextHopData.dSap      = dSap;
    addNextHopData.sSap      = sSap;
    addNextHopData.ctrl      = ctrl;
    addNextHopData.oui       = oui;
    addNextHopData.pid       = pid;
        
    pCbContext->pUserCallback = pCallback;   
    pCbContext->pUserContext  = pUserContext;

    /* send asynchronous message */
    IX_ERROR_CGT(ix_cc_msup_send_async_msg(
                 IX_CC_LLC_SNAP_ENCAP_MSG_ID,
                 _ix_cc_llc_snap_encap_cb_add_next_hop,
                 (void *)pCbContext,
                 IX_CC_LLC_SNAP_ENCAP_MSG_ADD_NEXT_HOP,
                 (void *)&addNextHopData,
                 sizeof(ix_cc_llc_snap_encap_add_next_hop_data_t)),
                 err,
                 IX_CC_LLC_SNAP_ENCAP_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING,
                 cleanup_context);
   
    return IX_SUCCESS;
                          
  cleanup_context:
    
    if (pCbContext != NULL)
    {
        ix_ossl_free(pCbContext);
    }
    
    return err;

} /* ix_cc_llc_snap_encap_async_add_next_hop */


/**
 ****************************************************************************
 * @ingroup LlcSnapEncap
 * Delete an entry in the Next Hop table
 * @description
 *    This message helper function builds and sends a "Delete Next Hop"
 *    message for the LLC Snap Encapsulation core component. All the user
 *    provided data are sent along to find the entry in the Next Hop table.
 *
 * @param nextHop - IN: Next Hop ID
 * @param pUserCallback - IN: pointer to the user callback function
 * @param pUserContext - IN: pointer to the user provided context data (opaque
 *                       for the LLC Snap Encap CC).
 *
 * @retval IX_SUCCESS - message was successfully built and sent 
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM - invalid pointer
 *                                                          in input parameters
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_MSG_LIBRARY - failed sending a message 
 * @retval IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED - Core Component not
 *                                                      initialized yet
 *
 *****************************************************************************/
ix_error
ix_cc_llc_snap_encap_async_delete_next_hop(
    ix_uint16 nextHop,
    ix_cc_llc_snap_encap_cb_delete_next_hop pCallback,
    void *pUserContext)
{
    ix_cc_llc_snap_encap_delete_next_hop_data_t deleteNextHopData;
    ix_cc_llc_snap_encap_delete_next_hop_callback_data_t* pCbContext;
    ix_error err = IX_SUCCESS;

    /* check if CC is initialized yet */
    if ((pLlcSnapEncapContext == NULL) ||
        (pLlcSnapEncapContext->initialized != TRUE))
    {
        /* Core Component not initialized */
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_NOT_INITIALIZED,
        ("LLC Snap Encap Msg helper: CC not initialized yet"));
    }

    /* check parameters' consistency */
    if (pCallback == NULL)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_INVALID_INPUT_PARAM,
        ("LLC Snap Encap Msg helper: Invalid pointer_pCallback"));
    }

    pCbContext = (ix_cc_llc_snap_encap_delete_next_hop_callback_data_t*) \
        ix_ossl_malloc( \
        sizeof(ix_cc_llc_snap_encap_delete_next_hop_callback_data_t));
    
    if (pCbContext == NULL)
    {
        return IX_ERROR_WARNING(
        IX_CC_LLC_SNAP_ENCAP_ERROR_MSG_LIBRARY,
        ("LLC Snap Encap Msg helper: No memory for context"));
    }

    /* prepare data to be sent in a message */
    deleteNextHopData.nextHop = nextHop;

    pCbContext->pUserCallback = pCallback;   
    pCbContext->pUserContext  = pUserContext;

    /* send asynchronous message */
    IX_ERROR_CGT(ix_cc_msup_send_async_msg(
                 IX_CC_LLC_SNAP_ENCAP_MSG_ID,
                 _ix_cc_llc_snap_encap_cb_delete_next_hop,
                 (void *)pCbContext,
                 IX_CC_LLC_SNAP_ENCAP_MSG_DELETE_NEXT_HOP,
                 (void *)&deleteNextHopData,
                 sizeof(ix_cc_llc_snap_encap_delete_next_hop_data_t)),
                 err,
                 IX_CC_LLC_SNAP_ENCAP_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING,
                 cleanup_context);
   
    return IX_SUCCESS;
                          
  cleanup_context:
    
    if (pCbContext != NULL)
    {
        ix_ossl_free(pCbContext);
    }
    
    return err;

} /* ix_cc_llc_snap_encap_async_delete_next_hop */


/*****************************************************************************
 * Abstract:
 *    This is an "Add Next Hop" internal callback function. Message support
 *    library calls this function to return the status of the requested
 *    asynchronous operation to the original "async" function caller.
 *
 * Parameters:
 *    result  - IN: result of the asynchronous operation
 *    pContext - IN: context provided by caller
 *    pMsg - IN: return message
 *    msgLength - IN: length of the message
 *
 * Return values:
 *    IX_SUCCESS - all operations ended successfully
 *    IX_CC_LLC_SNAP_ENCAP_ERROR_CALLBACK - user callback returns error message
 *
 *****************************************************************************/
ix_error
_ix_cc_llc_snap_encap_cb_add_next_hop(ix_error result,
                                      void* pContext,
                                      void* pMsg,
                                      ix_uint32 msgLength)
{
    ix_error err = IX_SUCCESS;
    ix_cc_llc_snap_encap_add_next_hop_callback_data_t* pCbData = NULL;
 
    pCbData = (ix_cc_llc_snap_encap_add_next_hop_callback_data_t*)pContext;
   
    if (pCbData != NULL)
    {
        /* invoke original caller's calback function */
        err = pCbData->pUserCallback(result,
                                     pCbData->pUserContext);
        
        ix_ossl_free(pContext);
        
        if (err != IX_SUCCESS)
        {
            return IX_ERROR_WARNING(
            IX_CC_LLC_SNAP_ENCAP_ERROR_CALLBACK,
            ("LLC Snap Encap Add Next Hop callback failed"));
        }
    }
       
    return IX_SUCCESS;
    
} /* _ix_cc_llc_snap_encap_cb_add_next_hop */


/*****************************************************************************
 * Abstract:
 *    This is a "Delete Next Hop" internal callback function. Message support
 *    library calls this function to return the status of the requested
 *    asynchronous operation to the original "async" function caller.
 *
 * Parameters:
 *    result  - IN: result of the asynchronous operation
 *    pContext - IN: context provided by caller
 *    pMsg - IN: return message
 *    msgLength - IN: length of the message
 *
 * Return values:
 *    IX_SUCCESS - all operations ended successfully
 *    IX_CC_LLC_SNAP_ENCAP_ERROR_CALLBACK - user callback returns error message
 *
 *****************************************************************************/
ix_error
_ix_cc_llc_snap_encap_cb_delete_next_hop(ix_error result,
                                         void* pContext,
                                         void* pMsg,
                                         ix_uint32 msgLength)
{
    ix_error err = IX_SUCCESS;
    ix_cc_llc_snap_encap_delete_next_hop_callback_data_t* pCbData = NULL;
 
    pCbData = (ix_cc_llc_snap_encap_delete_next_hop_callback_data_t*)pContext;
   
    if (pCbData != NULL)
    {
        /* invoke original caller's calback function */
        err = pCbData->pUserCallback(result,
                                     pCbData->pUserContext);
        
        ix_ossl_free(pContext);
        
        if (err != IX_SUCCESS)
        {
            return IX_ERROR_WARNING(
            IX_CC_LLC_SNAP_ENCAP_ERROR_CALLBACK,
            ("LLC Snap Encap Delete Next Hop callback failed"));
        }
    }
       
    return IX_SUCCESS;
    
} /* _ix_cc_llc_snap_encap_cb_delete_next_hop */

