C++程序  |  283行  |  9.21 KB

/******************************************************************************
 *
 *  Copyright (C) 2010-2012 Broadcom Corporation
 *
 *  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.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This is the implementation file for the NFA SNEP default server.
 *
 ******************************************************************************/
#include <string.h>
#include "nfa_sys.h"
#include "nfa_sys_int.h"
#include "nfa_snep_int.h"
#include "nfa_mem_co.h"
#include "nfa_dm_int.h"
#include "trace_api.h"

/*****************************************************************************
**  Global Variables
*****************************************************************************/

/* system manager control block definition */
#if NFA_DYNAMIC_MEMORY == FALSE
tNFA_SNEP_DEFAULT_CB nfa_snep_default_cb;
#endif

/*****************************************************************************
**  Static Functions
*****************************************************************************/

/*****************************************************************************
**  Constants
*****************************************************************************/

/*******************************************************************************
**
** Function         nfa_snep_default_init
**
** Description      Initialize NFA SNEP default server
**
**
** Returns          None
**
*******************************************************************************/
void nfa_snep_default_init (void)
{
    UINT8 xx;

    SNEP_TRACE_DEBUG0 ("nfa_snep_default_init ()");

    /* initialize control block */
    memset (&nfa_snep_default_cb, 0, sizeof (tNFA_SNEP_DEFAULT_CB));

    /* initialize non-zero value */
    nfa_snep_default_cb.server_handle = NFA_HANDLE_INVALID;

    for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
    {
        nfa_snep_default_cb.conn[xx].conn_handle = NFA_HANDLE_INVALID;
    }
}

/*******************************************************************************
**
** Function         nfa_snep_default_service_cback
**
** Description      Processing event to default SNEP server/client
**
**
** Returns          None
**
*******************************************************************************/
void nfa_snep_default_service_cback (tNFA_SNEP_EVT event, tNFA_SNEP_EVT_DATA *p_data)
{
    UINT8 xx;
    tNFA_SNEP_API_DISCONNECT api_disconnect;
    tNFA_SNEP_API_PUT_RESP   api_put_resp;

    SNEP_TRACE_DEBUG1 ("nfa_snep_default_service_cback () event:0x%X", event);

    switch (event)
    {
    case NFA_SNEP_REG_EVT:
        if (p_data->reg.status == NFA_STATUS_OK)
        {
            nfa_snep_default_cb.server_handle = p_data->reg.reg_handle;
        }
        else
        {
            SNEP_TRACE_ERROR0 ("Default SNEP server failed to register");
        }
        break;

    case NFA_SNEP_CONNECTED_EVT:
        if (p_data->connect.reg_handle == nfa_snep_default_cb.server_handle)
        {
            for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
            {
                if (nfa_snep_default_cb.conn[xx].conn_handle == NFA_HANDLE_INVALID)
                {
                    nfa_snep_default_cb.conn[xx].conn_handle = p_data->connect.conn_handle;
                    break;
                }
            }

            if (xx >= NFA_SNEP_DEFAULT_MAX_CONN)
            {
                SNEP_TRACE_ERROR1 ("Default SNEP server cannot handle more than %d connections",
                                  NFA_SNEP_DEFAULT_MAX_CONN);

                api_disconnect.conn_handle = p_data->connect.conn_handle;
                api_disconnect.flush       = TRUE;
                nfa_snep_disconnect ((tNFA_SNEP_MSG *) &api_disconnect);
            }
        }
        break;

    case NFA_SNEP_ALLOC_BUFF_EVT:
        if (p_data->alloc.req_code == NFA_SNEP_REQ_CODE_GET)
        {
            /*
            ** Default server doesn't support GET
            ** Send NFA_SNEP_RESP_CODE_NOT_IMPLM to peer
            */
            SNEP_TRACE_WARNING0 ("Default SNEP server doesn't support GET");
            p_data->alloc.p_buff    = NULL;
            p_data->alloc.resp_code = NFA_SNEP_RESP_CODE_NOT_IMPLM;
        }
        else /* NFA_SNEP_REQ_CODE_PUT */
        {
            p_data->alloc.p_buff = NULL;

            for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
            {
                if (nfa_snep_default_cb.conn[xx].conn_handle == p_data->alloc.conn_handle)
                {
                    if (p_data->alloc.ndef_length <= NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE)
                    {
                        /* allocate memory, allocated buffer will be returned in NFA_SNEP_PUT_REQ_EVT */
                        p_data->alloc.p_buff = (UINT8*) nfa_mem_co_alloc (p_data->alloc.ndef_length);
                    }

                    /* store buffer pointer in case of failure in the middle */
                    nfa_snep_default_cb.conn[xx].p_rx_ndef = p_data->alloc.p_buff;
                    break;
                }
            }
        }
        break;

    case NFA_SNEP_PUT_REQ_EVT:
        for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
        {
            if (nfa_snep_default_cb.conn[xx].conn_handle == p_data->put_req.conn_handle)
            {
                if (!nfa_snep_cb.is_dta_mode)
                {
                    nfa_dm_ndef_handle_message (NFA_STATUS_OK,
                                                p_data->put_req.p_ndef,
                                                p_data->put_req.ndef_length);
                }
#if (BT_TRACE_PROTOCOL == TRUE)
                else
                {
                    DispNDEFMsg (p_data->put_req.p_ndef,
                                 p_data->put_req.ndef_length, TRUE);
                }
#endif

                nfa_mem_co_free (p_data->put_req.p_ndef);
                nfa_snep_default_cb.conn[xx].p_rx_ndef = NULL;

                api_put_resp.conn_handle = p_data->put_req.conn_handle;
                api_put_resp.resp_code   = NFA_SNEP_RESP_CODE_SUCCESS;

                nfa_snep_put_resp ((tNFA_SNEP_MSG *) &api_put_resp);
                break;
            }
        }
        break;

    case NFA_SNEP_DISC_EVT:
        for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
        {
            if (nfa_snep_default_cb.conn[xx].conn_handle == p_data->disc.conn_handle)
            {
                nfa_snep_default_cb.conn[xx].conn_handle = NFA_HANDLE_INVALID;

                /* if buffer is not freed */
                if (nfa_snep_default_cb.conn[xx].p_rx_ndef)
                {
                    nfa_mem_co_free (nfa_snep_default_cb.conn[xx].p_rx_ndef);
                    nfa_snep_default_cb.conn[xx].p_rx_ndef  = NULL;
                }
                break;
            }
        }
        break;

    default:
        SNEP_TRACE_ERROR0 ("Unexpected event for default SNEP server");
        break;
    }
}

/*******************************************************************************
**
** Function         nfa_snep_start_default_server
**
** Description      Launching default SNEP server
**
**
** Returns          TRUE to deallocate message
**
*******************************************************************************/
BOOLEAN nfa_snep_start_default_server (tNFA_SNEP_MSG *p_msg)
{
    tNFA_SNEP_API_REG_SERVER msg;

    SNEP_TRACE_DEBUG0 ("nfa_snep_start_default_server ()");

    if (nfa_snep_default_cb.server_handle == NFA_HANDLE_INVALID)
    {
        msg.server_sap = NFA_SNEP_DEFAULT_SERVER_SAP;

        BCM_STRNCPY_S (msg.service_name, sizeof (msg.service_name),
                      "urn:nfc:sn:snep", LLCP_MAX_SN_LEN);
        msg.service_name[LLCP_MAX_SN_LEN] = 0;

        msg.p_cback = nfa_snep_default_service_cback;
        nfa_snep_reg_server ((tNFA_SNEP_MSG *) &msg);
    }

    (*p_msg->api_start_default_server.p_cback) (NFA_SNEP_DEFAULT_SERVER_STARTED_EVT, NULL);

    return TRUE;
}

/*******************************************************************************
**
** Function         nfa_snep_stop_default_server
**
** Description      Stoppping default SNEP server
**
**
** Returns          TRUE to deallocate message
**
*******************************************************************************/
BOOLEAN nfa_snep_stop_default_server (tNFA_SNEP_MSG *p_msg)
{
    tNFA_SNEP_API_DEREG msg;

    SNEP_TRACE_DEBUG0 ("nfa_snep_stop_default_server ()");

    if (nfa_snep_default_cb.server_handle != NFA_HANDLE_INVALID)
    {
        msg.reg_handle = nfa_snep_default_cb.server_handle;

        nfa_snep_dereg ((tNFA_SNEP_MSG *) &msg);

        nfa_snep_default_cb.server_handle = NFA_HANDLE_INVALID;
    }

    (*p_msg->api_stop_default_server.p_cback) (NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT, NULL);

    return TRUE;
}