Пример #1
0
/*************************************************************************
*
*   FUNCTION
*
*       mcapi_sclchan_available
*
*   DESCRIPTION
*
*       Non-blocking API routine to check for data on a connected scalar
*       channel.
*
*   INPUTS
*
*       receive_handle          The local handle identifer being checked
*                               for incoming data.
*       *mcapi_status           A pointer to memory that will be filled in
*                               with the status of the call.
*
*   OUTPUTS
*
*       The number of receive operations that are guaranteed to not block
*       waiting for incoming data.
*
*************************************************************************/
mcapi_uint_t mcapi_sclchan_available(mcapi_sclchan_recv_hndl_t receive_handle,
                                     mcapi_status_t *mcapi_status)
{
    MCAPI_GLOBAL_DATA   *node_data;
    mcapi_port_t        port_id;
    mcapi_node_t        node_id;
    mcapi_uint_t        msg_count = 0;
    MCAPI_ENDPOINT      *endp_ptr;

    /* Ensure the status pointer is valid. */
    if (mcapi_status)
    {
        /* Get the lock. */
        mcapi_lock_node_data();

        /* Get a pointer to the global node list. */
        node_data = mcapi_get_node_data();

        /* Get a pointer to the endpoint. */
        endp_ptr = mcapi_decode_local_endpoint(node_data, &node_id, &port_id,
                                               receive_handle, mcapi_status);

        if (endp_ptr)
        {
            /* Get the data. */
            mcapi_data_available(endp_ptr, MCAPI_CHAN_SCAL_TYPE, &msg_count,
                                 mcapi_status);
        }

        else if (*mcapi_status == MCAPI_ERR_ENDP_INVALID)
        {
            *mcapi_status = MCAPI_ERR_CHAN_INVALID;
        }

        /* Release the lock. */
        mcapi_unlock_node_data();
    }

    return (msg_count);

}
/*************************************************************************
*
*   FUNCTION
*
*       mcapi_sclchan_send_close_i
*
*   DESCRIPTION
*
*       Non-blocking API routine to close the send side of a scalar
*       channel.  Close calls are required on both the send and receive
*       side to properly close the channel.  Pending scalars at the
*       receiver are not discarded until the receive side is closed.
*       Attempts to transmit more data from a closed send side will
*       elicit an error.
*
*   INPUTS
*
*       send_handle             The local send handle identifier for
*                               the send side of the connection being
*                               closed.
*       *request                A pointer to memory that will be filled in
*                               with data relevant to the operation, so the
*                               status of the operation can later be checked.
*       *mcapi_status           A pointer to memory that will be filled in
*                               with the status of the call.
*
*   OUTPUTS
*
*       None.
*
*************************************************************************/
void mcapi_sclchan_send_close_i(mcapi_sclchan_send_hndl_t send_handle,
                                mcapi_request_t *request,
                                mcapi_status_t *mcapi_status)
{
    MCAPI_GLOBAL_DATA   *node_data;
    mcapi_port_t        port_id;
    mcapi_node_t        node_id;
    MCAPI_ENDPOINT      *endp_ptr;

    /* Ensure the status pointer is valid. */
    if (mcapi_status)
    {
        /* Get the lock. */
        mcapi_lock_node_data();

        /* Get a pointer to the global node list. */
        node_data = mcapi_get_node_data();

        /* Get a pointer to the endpoint. */
        endp_ptr = mcapi_decode_local_endpoint(node_data, &node_id, &port_id,
                                               send_handle, mcapi_status);

        if (endp_ptr)
        {
            /* Close the receive side of the connection. */
            mcapi_close(endp_ptr, MCAPI_CHAN_SCAL_TYPE, request,
                        MCAPI_ENDP_TX, mcapi_status);
        }

        else if (*mcapi_status == MCAPI_ERR_ENDP_INVALID)
        {
            *mcapi_status = MCAPI_ERR_CHAN_INVALID;
        }

        /* Release the lock. */
        mcapi_unlock_node_data();
    }

}
/*************************************************************************
*
*   FUNCTION
*
*       mcapi_set_endpoint_attribute
*
*   DESCRIPTION
*
*       API routine to set attributes specific to a local endpoint.
*
*   INPUTS
*
*       endpoint                The endpoint identifier on the local node
*                               of which to set the attribute.
*       attribute_num           The attribute to set.
*       *attribute              The new value of the attribute being set.
*       attribute_size          The number of bytes contained in *attribute.
*       *mcapi_status           A pointer to memory that will be filled in
*                               with the status of the call.
*
*   OUTPUTS
*
*       None.
*
*************************************************************************/
void mcapi_set_endpoint_attribute(mcapi_endpoint_t endpoint,
                                  mcapi_uint_t attribute_num,
                                  void *attribute,
                                  size_t attribute_size,
                                  mcapi_status_t *mcapi_status)
{
    MCAPI_GLOBAL_DATA   *node_data;
    MCAPI_ENDPOINT      *endp_ptr = MCAPI_NULL;
    mcapi_port_t        port_id;
    mcapi_node_t        node_id;

    /* Validate mcapi_status input parameter. */
    if (mcapi_status)
    {
        /* Validate attribute input parameter. */
        if (attribute)
        {
            /* Get the lock. */
            mcapi_lock_node_data();

            /* Get a pointer to the global node list. */
            node_data = mcapi_get_node_data();

            /* Get a pointer to the endpoint. */
            endp_ptr = mcapi_decode_local_endpoint(node_data, &node_id, &port_id,
                                                   endpoint, mcapi_status);

            /* Ensure the endpoint is valid. */
            if ( (*mcapi_status == MCAPI_SUCCESS) &&
                 (endp_ptr->mcapi_state != MCAPI_ENDP_CLOSED) )
            {
                /* Ensure the endpoint is not already connected. */
                if (!(endp_ptr->mcapi_state & MCAPI_ENDP_CONNECTING))
                {
                    switch (attribute_num)
                    {
                        case MCAPI_ATTR_ENDP_PRIO:

                            /* If the priority is the correct size */
                            if (attribute_size == sizeof(endp_ptr->mcapi_priority))
                            {
                                /* Ensure the priority is valid. */
                                if (*(mcapi_uint32_t*)attribute < MCAPI_PRIO_COUNT)
                                {
                                    /* Update the priority of the endpoint. */
                                    endp_ptr->mcapi_priority = *(mcapi_uint32_t*)attribute;

                                    *mcapi_status = MCAPI_SUCCESS;
                                }

                                else
                                {
                                    *mcapi_status = MCAPI_ERR_PARAMETER;
                                }
                            }

                            /* The priority value is the wrong size. */
                            else
                            {
                                *mcapi_status = MCAPI_ERR_ATTR_SIZE;
                            }

                            break;

                    default:

                        /* If there is a route associated with the endpoint. */
                        if (endp_ptr->mcapi_route)
                        {
                            /* If there is an interfae associated with the
                             * route.
                             */
                            if (endp_ptr->mcapi_route->mcapi_rt_int)
                            {
                                /* Call the interface-specific ioctl command. */
                                *mcapi_status =
                                    endp_ptr->mcapi_route->mcapi_rt_int->mcapi_ioctl(attribute_num,
                                                                                     attribute,
                                                                                     attribute_size);
                            }
                        }

                        else
                        {
                            /* Unknown attribute. */
                            *mcapi_status = MCAPI_ERR_ATTR_NUM;
                        }

                        break;
                    }
                }

                /* Attributes of an endpoint cannot be changed once the
                 * endpoint has been connected.
                 */
                else
                {
                    *mcapi_status = MCAPI_ERR_CHAN_CONNECTED;
                }
            }

            /* Release the lock. */
            mcapi_unlock_node_data();
        }

        /* The pointer for attribute is invalid. */
        else
        {
            *mcapi_status = MCAPI_ERR_PARAMETER;
        }
    }

}
Пример #4
0
/*************************************************************************
*
*   FUNCTION
*
*       pkt_send
*
*   DESCRIPTION
*
*       Send a packet over a connected channel.  Called by both
*       blocking and non-blocking transmission routines.
*
*   INPUTS
*
*       send_handle             The transmission handle.
*       *buffer                 A pointer to the data to transmit.
*       buffer_size             The number of bytes of data to transmit.
*       *request                A pointer to memory that will be filled in
*                               with data relevant to the operation, so the
*                               status of the operation can later be checked.
*       *mcapi_status           A pointer to memory that will be filled in
*                               with the status of the call.
*       timeout                 The amount of time to block for the operation
*                               to complete.
*
*   OUTPUTS
*
*       None.
*
*************************************************************************/
void pkt_send(mcapi_pktchan_send_hndl_t send_handle, void *buffer,
              size_t buffer_size, mcapi_request_t *request,
              mcapi_status_t *mcapi_status, mcapi_uint32_t timeout)
{
    MCAPI_GLOBAL_DATA   *node_data;
    MCAPI_ENDPOINT      *tx_endp_ptr = MCAPI_NULL;
    MCAPI_BUFFER        *tx_buf;
    mcapi_port_t        port_id;
    mcapi_node_t        node_id;

    /* Validate the status parameter. */
    if (mcapi_status)
    {
        /* Validate the input parameters. */
        if ( (request) && ((buffer) || ((!buffer) && (buffer_size == 0))) )
        {
            /* Lock the global data structure. */
            mcapi_lock_node_data();

            /* Get a pointer to the global node list. */
            node_data = mcapi_get_node_data();

            /* Get a pointer to the endpoint that is sending data. */
            tx_endp_ptr = mcapi_decode_local_endpoint(node_data, &node_id,
                                                      &port_id,
                                                      send_handle,
                                                      mcapi_status);

            /* Ensure the transmit endpoint is valid. */
            if (tx_endp_ptr)
            {
                /* Ensure the length of the buffer is valid. */
                if (buffer_size + MCAPI_HEADER_LEN <=
                    tx_endp_ptr->mcapi_route->mcapi_rt_int->mcapi_max_buf_size)
                {
                    /* Ensure this is a send handle and the connection
                     * is still good.
                     */
                    if ( (tx_endp_ptr->mcapi_state & MCAPI_ENDP_TX) &&
                         (tx_endp_ptr->mcapi_state & MCAPI_ENDP_CONNECTED) )
                    {
                        /* Ensure the handle is for a packet channel. */
                        if (tx_endp_ptr->mcapi_chan_type == MCAPI_CHAN_PKT_TYPE)
                        {
                            /* Get a transmission buffer. */
                            tx_buf = tx_endp_ptr->mcapi_route->mcapi_rt_int->
                                mcapi_get_buffer(tx_endp_ptr->mcapi_foreign_node_id,
                                                 buffer_size + MCAPI_HEADER_LEN,
                                                 tx_endp_ptr->mcapi_priority);

                            if (tx_buf)
                            {
                                /* Save a pointer to the tx interface. */
                                tx_buf->mcapi_dev_ptr =
                                    (MCAPI_POINTER)(tx_endp_ptr->mcapi_route->mcapi_rt_int);

                                /* Initialize the request structure. */
                                mcapi_init_request(request, MCAPI_REQ_TX_FIN);

                                /* Set up the request structure. */
                                request->mcapi_target_endp = send_handle;

                                /* Set the source node in the packet. */
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_SRC_NODE_OFFSET,
                                            tx_endp_ptr->mcapi_node_id);

                                /* Set the source port in the packet. */
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_SRC_PORT_OFFSET,
                                            tx_endp_ptr->mcapi_port_id);

                                /* Set the destination node in the packet. */
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_DEST_NODE_OFFSET,
                                            tx_endp_ptr->mcapi_foreign_node_id);

                                /* Set the destination port in the packet. */
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_DEST_PORT_OFFSET,
                                            tx_endp_ptr->mcapi_foreign_port_id);

                                /* Set the priority of the packet. */
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_PRIO_OFFSET,
                                            tx_endp_ptr->mcapi_priority);

                                /* Zero out the unused bits. */
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_UNUSED_OFFSET, 0);

                                /* Copy the data into the MCAPI buffer. */
                                memcpy(&tx_buf->buf_ptr[MCAPI_HEADER_LEN], buffer,
                                       buffer_size);

                                /* Set the length of the data in the buffer. */
                                tx_buf->buf_size = buffer_size + MCAPI_HEADER_LEN;

                                /* Pass the data to the transport layer driver. */
                                *mcapi_status = tx_endp_ptr->mcapi_route->mcapi_rt_int->
                                    mcapi_tx_output(tx_buf, buffer_size,
                                                    tx_endp_ptr->mcapi_priority,
                                                    tx_endp_ptr);

                                /* The data was transmitted. */
                                if (*mcapi_status == MCAPI_SUCCESS)
                                {
                                    /* Set the status to success. */
                                    request->mcapi_status = MCAPI_SUCCESS;

                                    /* Record the number of bytes sent. */
                                    request->mcapi_byte_count = buffer_size;
                                }

                                /* The data could not be transmitted. */
                                else
                                {
                                    request->mcapi_status = *mcapi_status;

                                    /* Indicate that no data was sent. */
                                    request->mcapi_byte_count = 0;

                                    /* Return the transmission buffer to the list
                                     * of free buffers in the system.
                                     */
                                    ((MCAPI_INTERFACE*)(tx_buf->mcapi_dev_ptr))->
                                        mcapi_recover_buffer(tx_buf);
                                }
                            }

                            /* There are no transmission buffers available to
                             * process this request.
                             */
                            else
                            {
                                *mcapi_status = MCAPI_ERR_TRANSMISSION;
                            }
                        }

                        /* Trying to send a packet over a scalar channel. */
                        else
                        {
                            *mcapi_status = MCAPI_ERR_CHAN_TYPE;
                        }
                    }

                    /* Attempting to send over a receive channel. */
                    else
                    {
                        /* If this is a receive channel. */
                        if (tx_endp_ptr->mcapi_state & MCAPI_ENDP_RX)
                        {
                            *mcapi_status = MCAPI_ERR_CHAN_DIRECTION;
                        }

                        /* Otherwise, the connection has been closed. */
                        else
                        {
                            *mcapi_status = MCAPI_ERR_CHAN_INVALID;
                        }
                    }
                }

                /* The data size is too big. */
                else
                {
                    *mcapi_status = MCAPI_ERR_PKT_SIZE;
                }
            }

            /* One of the endpoints is invalid. */
            else
            {
                *mcapi_status = MCAPI_ERR_CHAN_INVALID;
            }

            /* Unlock the global data structure. */
            mcapi_unlock_node_data();
        }

        /* The buffer is invalid. */
        else
        {
            *mcapi_status = MCAPI_ERR_PARAMETER;
        }
    }

}