OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.swp.api/] [openmcapi/] [1.0/] [test/] [mgmt_svc.c] - Rev 145

Compare with Previous | Blame | View Log

/*
 * Copyright (c) 2010, Mentor Graphics Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
 
/*
*   FILENAME
*
*       mgmt_svc.c
*
*
*************************************************************************/
 
#include <stdio.h>
#include "mgmt_svc.h"
#include "support_suite/mcapid_support.h"
#include "mcapid.h"
 
/************************************************************************
*
*   FUNCTION
*
*       MCAPID_Mgmt_Service
*
*   DESCRIPTION
*
*       This function processes incoming packets instructing the node
*       to create an endpoint, delete an endpoint, etc.
*
*************************************************************************/
MCAPI_THREAD_ENTRY(MCAPID_Mgmt_Service)
{
    size_t                      rx_len;
    MCAPID_STRUCT               *mcapi_struct = (MCAPID_STRUCT*)argv;
    unsigned char               buffer[MCAPID_MGMT_PKT_LEN];
    mcapi_pktchan_send_hndl_t   tx_handle;
    mcapi_pktchan_recv_hndl_t   rx_handle;
    int                         tx_handle_in_use = MCAPI_FALSE,
                                rx_handle_in_use = MCAPI_FALSE;
    mcapi_sclchan_send_hndl_t   tx_handle_scl;
    mcapi_sclchan_recv_hndl_t   rx_handle_scl;
    int                         tx_handle_scl_in_use = MCAPI_FALSE,
                                rx_handle_scl_in_use = MCAPI_FALSE;
    mcapi_request_t             pkt_tx_request, pkt_rx_request,
                                scl_tx_request, scl_rx_request;
    mcapi_endpoint_t            endpoint;
    mcapi_node_t                this_node;
    mcapi_status_t              status;
    mcapi_port_t                port;
    mcapi_priority_t            prio;
    mcapi_boolean_t             complete;
    mcapi_request_t             request;
    size_t                      size;
 
    this_node = mcapi_get_node_id(&status);
 
    for (;;)
    {
        /* Wait for a message. */
        mcapi_msg_recv(mcapi_struct->local_endp, buffer, MCAPID_MGMT_PKT_LEN,
                       &rx_len, &mcapi_struct->status);
 
        if (mcapi_struct->status == MCAPI_SUCCESS)
        {
            /* Sleep the appropriate amount of time - this gives the other side
             * time to issue a command before the management task causes an
             * action.
             */
            MCAPID_Sleep(mcapi_get32(buffer, MCAPID_MGMT_PAUSE_OFFSET));
 
            /* Determine the type of message. */
            switch (mcapi_get32(buffer, MCAPID_MGMT_TYPE_OFFSET))
            {
                /* Create an endpoint. */
                case MCAPID_MGMT_CREATE_ENDP:
 
                    port = mcapi_get32(buffer, MCAPID_MGMT_FOREIGN_PORT_OFFSET);
 
                    /* Create the endpoint with specified port ID. */
                    mcapi_create_endpoint(port, &mcapi_struct->status);
                    if (mcapi_struct->status != MCAPI_SUCCESS)
                        printf("error creating endport %d (%d)\n", port,
                               mcapi_struct->status);
 
                    break;
 
                /* Delete an endpoint. */
                case MCAPID_MGMT_DELETE_ENDP:
 
                    port = mcapi_get32(buffer, MCAPID_MGMT_FOREIGN_PORT_OFFSET);
                    mcapi_get_endpoint_i(this_node, port, &endpoint, &request,
                                         &status);
                    complete = mcapi_wait(&request, &size, &status, 0);
 
                    if (complete && (status == MCAPI_SUCCESS))
                    {
                        /* Delete the endpoint. */
                        mcapi_delete_endpoint(endpoint, &mcapi_struct->status);
                        if (mcapi_struct->status != MCAPI_SUCCESS)
                            printf("error deleting endport %d (%d)\n", port,
                                   mcapi_struct->status);
                    }
                    else
                    {
                        printf("%s: tried to delete a non-existent endpoint!\n",
                               __func__);
                    }
 
                    break;
 
                /* Send a blocking message. */
                case MCAPID_MGMT_TX_BLCK_MSG:
 
                    port = mcapi_get32(buffer, MCAPID_MGMT_FOREIGN_PORT_OFFSET);
                    mcapi_get_endpoint_i(this_node, port, &endpoint, &request,
                                         &status);
                    complete = mcapi_wait(&request, &size, &status, 0);
 
                    if (complete && (status == MCAPI_SUCCESS))
                    {
                        prio = mcapi_get32(buffer, MCAPID_MGMT_PRIO_OFFSET);
 
                        /* Send this packet back to the other side. */
                        mcapi_msg_send(endpoint,
                                       mcapi_get32(buffer, MCAPID_MGMT_LOCAL_ENDP_OFFSET),
                                       buffer, rx_len, prio,
                                       &mcapi_struct->status);
                    }
                    else
                    {
                        printf("%s: tried to delete a non-existent endpoint!\n",
                               __func__);
                    }
 
                    break;
 
                /* Send a non-blocking message. */
                case MCAPID_MGMT_TX_NONBLCK_MSG:
 
                    port = mcapi_get32(buffer, MCAPID_MGMT_FOREIGN_PORT_OFFSET);
                    mcapi_get_endpoint_i(this_node, port, &endpoint, &request,
                                         &status);
                    complete = mcapi_wait(&request, &size, &status, 0);
 
                    if (complete && (status == MCAPI_SUCCESS))
                    {
                        prio = mcapi_get32(buffer, MCAPID_MGMT_PRIO_OFFSET);
 
                        /* Send this packet back to the other side. */
                        mcapi_msg_send_i(endpoint,
                                         mcapi_get32(buffer, MCAPID_MGMT_LOCAL_ENDP_OFFSET),
                                         buffer, rx_len, prio,
                                         &mcapi_struct->request,
                                         &mcapi_struct->status);
                    }
                    else
                    {
                        printf("%s: tried to send msg to a non-existent "
                               "endpoint!\n", __func__);
                    }
 
                    break;
 
                /* Open a local endpoint as a sender. */
                case MCAPID_MGMT_OPEN_TX_SIDE_PKT:
 
                    /* Only one transmit handle can be open on the
                     * management service thread at a time.
                     */
                    if (tx_handle_in_use == MCAPI_FALSE)
                    {
                        port = mcapi_get32(buffer,
                                           MCAPID_MGMT_FOREIGN_PORT_OFFSET);
                        mcapi_get_endpoint_i(this_node, port, &endpoint,
                                             &request, &status);
                        complete = mcapi_wait(&request, &size, &status, 0);
 
                        if (complete && (status == MCAPI_SUCCESS))
                        {
                            mcapi_open_pktchan_send_i(&tx_handle,
                                                      endpoint,
                                                      &pkt_tx_request,
                                                      &mcapi_struct->status);
 
                            if ( (mcapi_struct->status == MCAPI_SUCCESS) ||
                                 (mcapi_struct->status == MGC_MCAPI_ERR_NOT_CONNECTED) )
                            {
                                tx_handle_in_use = MCAPI_TRUE;
                            }
                        }
                        else
                        {
                            printf("%s: tried to open a non-existent "
                                   "endpoint (for pktchan send)!\n", __func__);
                        }
                    }
 
                    else
                    {
                        mcapi_struct->status = -1;
                    }
 
                    break;
 
                /* Open a local endpoint as a receiver. */
                case MCAPID_MGMT_OPEN_RX_SIDE_PKT:
 
                    /* Only one receive handle can be open on the management
                     * service thread at a time.
                     */
                    if (rx_handle_in_use == MCAPI_FALSE)
                    {
                        port = mcapi_get32(buffer,
                                           MCAPID_MGMT_FOREIGN_PORT_OFFSET);
                        mcapi_get_endpoint_i(this_node, port, &endpoint,
                                             &request, &status);
                        complete = mcapi_wait(&request, &size, &status, 0);
 
                        if (status == MCAPI_SUCCESS)
                        {
                            mcapi_open_pktchan_recv_i(&rx_handle,
                                                      endpoint,
                                                      &pkt_rx_request,
                                                      &mcapi_struct->status);
 
                            if ( (mcapi_struct->status == MCAPI_SUCCESS) ||
                                 (mcapi_struct->status == MGC_MCAPI_ERR_NOT_CONNECTED) )
                            {
                                rx_handle_in_use = MCAPI_TRUE;
                            }
                        }
                        else
                        {
                            printf("%s: tried to open a non-existent "
                                   "endpoint (for pktchan recv)!\n", __func__);
                        }
                    }
 
                    else
                    {
                        mcapi_struct->status = -1;
                    }
 
                    break;
 
                /* Close the send side. */
                case MCAPID_MGMT_CLOSE_TX_SIDE_PKT:
 
                    mcapi_packetchan_send_close_i(tx_handle, &mcapi_struct->request,
                                                  &mcapi_struct->status);
 
                    if (mcapi_struct->status == MCAPI_SUCCESS)
                    {
                        tx_handle_in_use = MCAPI_FALSE;
                    }
 
                    break;
 
                /* Close the receive side. */
                case MCAPID_MGMT_CLOSE_RX_SIDE_PKT:
 
                    mcapi_packetchan_recv_close_i(rx_handle, &mcapi_struct->request,
                                                  &mcapi_struct->status);
 
                    if (mcapi_struct->status == MCAPI_SUCCESS)
                    {
                        rx_handle_in_use = MCAPI_FALSE;
                    }
 
                    break;
 
                case MCAPID_TX_PKT:
 
                    mcapi_pktchan_send(tx_handle, buffer, MCAPID_MGMT_PKT_LEN,
                                       &mcapi_struct->status);
 
                    break;
 
                /* Open a local endpoint as a sender. */
                case MCAPID_MGMT_OPEN_TX_SIDE_SCL:
 
                    /* Only one transmit handle can be open on the management
                     * service thread at a time.
                     */
                    if (tx_handle_scl_in_use == MCAPI_FALSE)
                    {
                        port = mcapi_get32(buffer,
                                           MCAPID_MGMT_FOREIGN_PORT_OFFSET);
                        mcapi_get_endpoint_i(this_node, port, &endpoint,
                                             &request, &status);
                        complete = mcapi_wait(&request, &size, &status, 0);
 
                        if (complete && (status == MCAPI_SUCCESS))
                        {
                            mcapi_open_sclchan_send_i(&tx_handle_scl,
                                                      endpoint,
                                                      &scl_tx_request,
                                                      &mcapi_struct->status);
 
                            if ( (mcapi_struct->status == MCAPI_SUCCESS) ||
                                 (mcapi_struct->status == MGC_MCAPI_ERR_NOT_CONNECTED) )
                            {
                                tx_handle_scl_in_use = MCAPI_TRUE;
                            }
                        }
                        else
                        {
                            printf("%s: tried to open a non-existent "
                                   "endpoint (for scalars)!\n", __func__);
                        }
                    }
 
                    else
                    {
                        mcapi_struct->status = -1;
                    }
 
                    break;
 
                /* Open a local endpoint as a receiver. */
                case MCAPID_MGMT_OPEN_RX_SIDE_SCL:
 
                    /* Only one receive handle can be open on the management
                     * service thread at a time.
                     */
                    if (rx_handle_scl_in_use == MCAPI_FALSE)
                    {
                        port = mcapi_get32(buffer,
                                           MCAPID_MGMT_FOREIGN_PORT_OFFSET);
                        mcapi_get_endpoint_i(this_node, port, &endpoint,
                                             &request, &status);
                        complete = mcapi_wait(&request, &size, &status, 0);
 
                        if (complete && (status == MCAPI_SUCCESS))
                        {
                            mcapi_open_sclchan_recv_i(&rx_handle_scl,
                                                      endpoint,
                                                      &scl_rx_request,
                                                      &mcapi_struct->status);
 
                            if ( (mcapi_struct->status == MCAPI_SUCCESS) ||
                                 (mcapi_struct->status == MGC_MCAPI_ERR_NOT_CONNECTED) )
                            {
                                rx_handle_scl_in_use = MCAPI_TRUE;
                            }
                        }
                        else
                        {
                            printf("%s: tried to open a non-existent "
                                   "endpoint (for scalars)!\n", __func__);
                        }
                    }
 
                    else
                    {
                        mcapi_struct->status = -1;
                    }
 
                    break;
 
                /* Close the send side. */
                case MCAPID_MGMT_CLOSE_TX_SIDE_SCL:
 
                    mcapi_sclchan_send_close_i(tx_handle_scl, &mcapi_struct->request,
                                               &mcapi_struct->status);
 
                    if (mcapi_struct->status == MCAPI_SUCCESS)
                    {
                        tx_handle_scl_in_use = MCAPI_FALSE;
                    }
 
                    break;
 
                /* Close the receive side. */
                case MCAPID_MGMT_CLOSE_RX_SIDE_SCL:
 
                    mcapi_sclchan_recv_close_i(rx_handle_scl, &mcapi_struct->request,
                                               &mcapi_struct->status);
 
                    if (mcapi_struct->status == MCAPI_SUCCESS)
                    {
                        rx_handle_scl_in_use = MCAPI_FALSE;
                    }
 
                    break;
 
                /* Send a 64-bit scalar. */
                case MCAPID_TX_64_BIT_SCL:
 
                    mcapi_sclchan_send_uint64(tx_handle_scl, MCAPID_64BIT_SCALAR,
                                              &mcapi_struct->status);
 
                    break;
 
                /* Send a 32-bit scalar. */
                case MCAPID_TX_32_BIT_SCL:
 
                    mcapi_sclchan_send_uint32(tx_handle_scl, MCAPID_32BIT_SCALAR,
                                              &mcapi_struct->status);
 
                    break;
 
                /* Send a 16-bit scalar. */
                case MCAPID_TX_16_BIT_SCL:
 
                    mcapi_sclchan_send_uint16(tx_handle_scl, MCAPID_16BIT_SCALAR,
                                              &mcapi_struct->status);
 
                    break;
 
                /* Send a 8-bit scalar. */
                case MCAPID_TX_8_BIT_SCL:
 
                    mcapi_sclchan_send_uint8(tx_handle_scl, MCAPID_8BIT_SCALAR,
                                             &mcapi_struct->status);
 
                    break;
 
                case MCAPID_NO_OP:
 
                    /* NO OP just ACKs back a successful response. */
                    mcapi_struct->status = MCAPI_SUCCESS;
 
                    break;
 
                default:
 
                    mcapi_struct->status = -1;
                    break;
            }
 
            /* Put the status in the packet. */
            mcapi_put32(buffer, MCAPID_MGMT_STATUS_OFFSET, mcapi_struct->status);
 
            prio = mcapi_get32(buffer, MCAPID_MGMT_PRIO_OFFSET);
 
            /* Send the response using the specified priority. */
            mcapi_msg_send(mcapi_struct->local_endp,
                           mcapi_get32(buffer, MCAPID_MGMT_LOCAL_ENDP_OFFSET),
                           buffer, rx_len, prio, &mcapi_struct->status);
        }
 
        /* The service has been shut down. */
        else
        {
            /* Terminate this task. */
            MCAPI_Cleanup_Task();
 
            break;
        }
    }
 
} /* MCAPID_Mgmt_Service */
 
/************************************************************************
*
*   FUNCTION
*
*       MCAPID_TX_Mgmt_Message
*
*   DESCRIPTION
*
*       Transmit a service message to the management endpoint.
*
*************************************************************************/
mcapi_status_t MCAPID_TX_Mgmt_Message(MCAPID_STRUCT *mcapi_struct,
                                      mcapi_uint32_t type,
                                      mcapi_port_t foreign_port,
                                      mcapi_endpoint_t local_endp,
                                      mcapi_uint32_t pause,
                                      mcapi_uint32_t priority)
{
    unsigned char   buffer[MCAPID_MGMT_PKT_LEN];
    mcapi_status_t  status;
 
    /* Set the type of service to complete. */
    mcapi_put32(buffer, MCAPID_MGMT_TYPE_OFFSET, type);
 
    /* Set the port of the foreign endpoint to use. */
    mcapi_put32(buffer, MCAPID_MGMT_FOREIGN_PORT_OFFSET, foreign_port);
 
    /* Zero out status. */
    mcapi_put32(buffer, MCAPID_MGMT_STATUS_OFFSET, 0);
 
    /* Set the millisecond pause before performing the service. */
    mcapi_put32(buffer, MCAPID_MGMT_PAUSE_OFFSET, pause);
 
    /* Set the endpoint to respond to on this node. */
    mcapi_put32(buffer, MCAPID_MGMT_LOCAL_ENDP_OFFSET, local_endp);
 
    /* Set the priority the receiver should use when responding. */
    mcapi_put32(buffer, MCAPID_MGMT_PRIO_OFFSET, priority);
 
    /* If this is a cancel or wait request, store the address of the request
     * being canceled in the status field of the packet.
     */
    if ( (type == MCAPID_CANCEL_REQUEST) || (type == MCAPID_WAIT_REQUEST) )
    {
        mcapi_put32(buffer, MCAPID_MGMT_STATUS_OFFSET,
                    (mcapi_uint32_t)&mcapi_struct->request);
    }
 
    /* Send the request. */
    mcapi_msg_send(mcapi_struct->local_endp, mcapi_struct->foreign_endp,
                   buffer, MCAPID_MGMT_PKT_LEN, priority, &status);
 
    return (status);
 
} /* MCAPID_TX_Mgmt_Message */
 
/************************************************************************
*
*   FUNCTION
*
*       MCAPID_RX_Mgmt_Response
*
*   DESCRIPTION
*
*       Receives the response to a service message from the management
*       endpoint.
*
*************************************************************************/
mcapi_status_t MCAPID_RX_Mgmt_Response(MCAPID_STRUCT *mcapi_struct)
{
    unsigned char   buffer[MCAPID_MGMT_PKT_LEN];
    mcapi_status_t  status, cncl_stat;
    mcapi_request_t request;
    size_t          rx_len;
 
    /* Receive the message. */
    mcapi_msg_recv_i(mcapi_struct->local_endp, buffer, MCAPID_MGMT_PKT_LEN,
                     &request, &status);
 
    if (status == MCAPI_SUCCESS)
    {
        mcapi_wait(&request, &rx_len, &status, 5000);
 
        if (status == MCAPI_SUCCESS)
        {
            /* Extract the status of the operation. */
            status = mcapi_get32(buffer, MCAPID_MGMT_STATUS_OFFSET);
        }
 
        else
        {
            mcapi_cancel(&request, &cncl_stat);
        }
    }
 
    return (status);
 
} /* MCAPID_RX_Mgmt_Response */
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.