C++程序  |  621行  |  21.86 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.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  NFA SNEP interface to LLCP
 *
 ******************************************************************************/
#include <string.h>
#include "nfa_api.h"
#include "nfa_sys.h"
#include "nfa_sys_int.h"
#include "nfa_snep_int.h"
#include "nfa_mem_co.h"

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

/*******************************************************************************
**
** Function         NFA_SnepStartDefaultServer
**
** Description      This function is called to listen to SAP, 0x04 as SNEP default
**                  server ("urn:nfc:sn:snep") on LLCP.
**
**                  NFA_SNEP_DEFAULT_SERVER_STARTED_EVT without data will be returned.
**
** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
**                  should happen before calling this function
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepStartDefaultServer (tNFA_SNEP_CBACK *p_cback)
{
    tNFA_SNEP_API_START_DEFAULT_SERVER *p_msg;

    SNEP_TRACE_API0 ("NFA_SnepStartDefaultServer ()");

    if (p_cback == NULL)
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepStartDefaultServer (): p_cback is NULL");
        return (NFA_STATUS_INVALID_PARAM);
    }

    if ((p_msg = (tNFA_SNEP_API_START_DEFAULT_SERVER *) GKI_getbuf (sizeof (tNFA_SNEP_API_START_DEFAULT_SERVER))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_START_DEFAULT_SERVER_EVT;
        p_msg->p_cback   = p_cback;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepStopDefaultServer
**
** Description      This function is called to stop SNEP default server on LLCP.
**
**                  NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT without data will be returned.
**
** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
**                  should happen before calling this function
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepStopDefaultServer (tNFA_SNEP_CBACK *p_cback)
{
    tNFA_SNEP_API_STOP_DEFAULT_SERVER *p_msg;

    SNEP_TRACE_API0 ("NFA_SnepStopDefaultServer ()");

    if (p_cback == NULL)
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepStopDefaultServer (): p_cback is NULL");
        return (NFA_STATUS_INVALID_PARAM);
    }

    if ((p_msg = (tNFA_SNEP_API_STOP_DEFAULT_SERVER *) GKI_getbuf (sizeof (tNFA_SNEP_API_STOP_DEFAULT_SERVER))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT;
        p_msg->p_cback   = p_cback;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepRegisterServer
**
** Description      This function is called to listen to a SAP as SNEP server.
**
**                  If server_sap is set to NFA_SNEP_ANY_SAP, then NFA will allocate
**                  a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
**
**                  NFC Forum default SNEP server ("urn:nfc:sn:snep") may be launched
**                  by NFA_SnepStartDefaultServer().
**
**                  NFA_SNEP_REG_EVT will be returned with status, handle and service name.
**
** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
**                  should happen before calling this function
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepRegisterServer (UINT8           server_sap,
                                    char            *p_service_name,
                                    tNFA_SNEP_CBACK *p_cback)
{
    tNFA_SNEP_API_REG_SERVER *p_msg;

    SNEP_TRACE_API2 ("NFA_SnepRegisterServer (): SAP:0x%X, SN:<%s>", server_sap, p_service_name);

    if ((p_service_name == NULL) || (p_cback == NULL))
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepRegisterServer (): p_service_name or p_cback is NULL");
        return (NFA_STATUS_INVALID_PARAM);
    }

    if ((p_msg = (tNFA_SNEP_API_REG_SERVER *) GKI_getbuf (sizeof (tNFA_SNEP_API_REG_SERVER))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_REG_SERVER_EVT;

        p_msg->server_sap = server_sap;

        BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name),
                       p_service_name, LLCP_MAX_SN_LEN);
        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;

        p_msg->p_cback = p_cback;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepRegisterClient
**
** Description      This function is called to register SNEP client.
**                  NFA_SNEP_REG_EVT will be returned with status, handle
**                  and zero-length service name.
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_INVALID_PARAM if p_cback is NULL
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepRegisterClient (tNFA_SNEP_CBACK *p_cback)
{
    tNFA_SNEP_API_REG_CLIENT *p_msg;

    SNEP_TRACE_API0 ("NFA_SnepRegisterClient ()");

    if (p_cback == NULL)
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepRegisterClient (): p_cback is NULL");
        return (NFA_STATUS_INVALID_PARAM);
    }

    if ((p_msg = (tNFA_SNEP_API_REG_CLIENT *) GKI_getbuf (sizeof (tNFA_SNEP_API_REG_CLIENT))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_REG_CLIENT_EVT;

        p_msg->p_cback = p_cback;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepDeregister
**
** Description      This function is called to stop listening as SNEP server
**                  or SNEP client. Application shall use reg_handle returned in
**                  NFA_SNEP_REG_EVT.
**
** Note:            If this function is called to de-register a SNEP server and RF
**                  discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
**                  should happen before calling this function
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_BAD_HANDLE if handle is not valid
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepDeregister (tNFA_HANDLE reg_handle)
{
    tNFA_SNEP_API_DEREG *p_msg;
    tNFA_HANDLE          xx;

    SNEP_TRACE_API1 ("NFA_SnepDeregister (): reg_handle:0x%X", reg_handle);

    xx = reg_handle & NFA_HANDLE_MASK;

    if (  (xx >= NFA_SNEP_MAX_CONN)
        ||(nfa_snep_cb.conn[xx].p_cback == NULL)  )
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepDeregister (): Handle is invalid or not registered");
        return (NFA_STATUS_BAD_HANDLE);
    }

    if ((p_msg = (tNFA_SNEP_API_DEREG *) GKI_getbuf (sizeof (tNFA_SNEP_API_DEREG))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_DEREG_EVT;

        p_msg->reg_handle = reg_handle;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepConnect
**
** Description      This function is called by client to create data link connection
**                  to SNEP server on peer device.
**
**                  Client handle and service name of server to connect shall be provided.
**                  A conn_handle will be returned in NFA_SNEP_CONNECTED_EVT, if
**                  successfully connected. Otherwise NFA_SNEP_DISC_EVT will be returned.
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_BAD_HANDLE if handle is not valid
**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepConnect (tNFA_HANDLE     client_handle,
                             char            *p_service_name)
{
    tNFA_SNEP_API_CONNECT *p_msg;
    tNFA_HANDLE            xx;

    SNEP_TRACE_API1 ("NFA_SnepConnect(): client_handle:0x%X", client_handle);

    xx = client_handle & NFA_HANDLE_MASK;

    if (  (xx >= NFA_SNEP_MAX_CONN)
        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_CLIENT))  )
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepConnect (): Client handle is invalid");
        return (NFA_STATUS_BAD_HANDLE);
    }

    if (p_service_name == NULL)
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepConnect (): p_service_name is NULL");
        return (NFA_STATUS_INVALID_PARAM);
    }

    if ((p_msg = (tNFA_SNEP_API_CONNECT*) GKI_getbuf (sizeof (tNFA_SNEP_API_CONNECT))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_CONNECT_EVT;

        p_msg->client_handle = client_handle;
        BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name),
                       p_service_name, LLCP_MAX_SN_LEN);
        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepGet
**
** Description      This function is called by client to send GET request.
**
**                  Application shall allocate a buffer and put NDEF message with
**                  desired record type to get from server. NDEF message from server
**                  will be returned in the same buffer with NFA_SNEP_GET_RESP_EVT.
**                  The size of buffer will be used as "Acceptable Length".
**
**                  NFA_SNEP_GET_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
**                  through registered p_cback. Application may free the buffer
**                  after receiving these events.
**
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_BAD_HANDLE if handle is not valid
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepGet (tNFA_HANDLE     conn_handle,
                         UINT32          buff_length,
                         UINT32          ndef_length,
                         UINT8           *p_ndef_buff)
{
    tNFA_SNEP_API_GET_REQ *p_msg;
    tNFA_HANDLE            xx;

    SNEP_TRACE_API1 ("NFA_SnepGet (): conn_handle:0x%X", conn_handle);

    xx = conn_handle & NFA_HANDLE_MASK;

    if (  (xx >= NFA_SNEP_MAX_CONN)
        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_CLIENT))  )
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepGet (): Connection handle is invalid");
        return (NFA_STATUS_BAD_HANDLE);
    }

    if ((p_msg = (tNFA_SNEP_API_GET_REQ *) GKI_getbuf (sizeof (tNFA_SNEP_API_GET_REQ))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_GET_REQ_EVT;

        p_msg->conn_handle = conn_handle;
        p_msg->buff_length = buff_length;
        p_msg->ndef_length = ndef_length;
        p_msg->p_ndef_buff = p_ndef_buff;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepPut
**
** Description      This function is called by client to send PUT request.
**
**                  Application shall allocate a buffer and put desired NDEF message
**                  to send to server.
**
**                  NFA_SNEP_PUT_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
**                  through registered p_cback. Application may free the buffer after
**                  receiving these events.
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_BAD_HANDLE if handle is not valid
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepPut (tNFA_HANDLE     conn_handle,
                         UINT32          ndef_length,
                         UINT8           *p_ndef_buff)
{
    tNFA_SNEP_API_PUT_REQ *p_msg;
    tNFA_HANDLE            xx;

    SNEP_TRACE_API1 ("NFA_SnepPut (): conn_handle:0x%X", conn_handle);

    xx = conn_handle & NFA_HANDLE_MASK;

    if (  (xx >= NFA_SNEP_MAX_CONN)
        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_CLIENT))  )
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepPut (): Connection handle is invalid");
        return (NFA_STATUS_BAD_HANDLE);
    }

    if ((p_msg = (tNFA_SNEP_API_PUT_REQ *) GKI_getbuf (sizeof (tNFA_SNEP_API_PUT_REQ))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_PUT_REQ_EVT;

        p_msg->conn_handle = conn_handle;
        p_msg->ndef_length = ndef_length;
        p_msg->p_ndef_buff = p_ndef_buff;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepGetResponse
**
** Description      This function is called by server to send response of GET request.
**
**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
**                  it shall allocate a buffer for incoming NDEF message and
**                  pass the pointer within callback context. This buffer will be
**                  returned with NFA_SNEP_GET_REQ_EVT after receiving complete
**                  NDEF message. If buffer is not allocated, NFA_SNEP_RESP_CODE_NOT_FOUND
**                  (Note:There is no proper response code for this case)
**                  or NFA_SNEP_RESP_CODE_REJECT will be sent to client.
**
**                  Server application shall provide conn_handle which is received in
**                  NFA_SNEP_GET_REQ_EVT.
**
**                  Server application shall allocate a buffer and put NDEF message if
**                  response code is NFA_SNEP_RESP_CODE_SUCCESS. Otherwise, ndef_length
**                  shall be set to zero.
**
**                  NFA_SNEP_GET_RESP_CMPL_EVT or NFA_SNEP_DISC_EVT will be returned
**                  through registered callback function. Application may free
**                  the buffer after receiving these events.
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_BAD_HANDLE if handle is not valid
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepGetResponse (tNFA_HANDLE         conn_handle,
                                 tNFA_SNEP_RESP_CODE resp_code,
                                 UINT32              ndef_length,
                                 UINT8               *p_ndef_buff)
{
    tNFA_SNEP_API_GET_RESP *p_msg;
    tNFA_HANDLE            xx;

    SNEP_TRACE_API1 ("NFA_SnepGetResponse (): conn_handle:0x%X", conn_handle);

    xx = conn_handle & NFA_HANDLE_MASK;

    if (  (xx >= NFA_SNEP_MAX_CONN)
        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_SERVER))  )
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepGetResponse (): Handle is invalid");
        return (NFA_STATUS_BAD_HANDLE);
    }

    if ((p_msg = (tNFA_SNEP_API_GET_RESP *) GKI_getbuf (sizeof (tNFA_SNEP_API_GET_RESP))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_GET_RESP_EVT;

        p_msg->conn_handle = conn_handle;
        p_msg->resp_code   = resp_code;
        p_msg->ndef_length = ndef_length;
        p_msg->p_ndef_buff = p_ndef_buff;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}


/*******************************************************************************
**
** Function         NFA_SnepPutResponse
**
** Description      This function is called by server to send response of PUT request.
**
**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
**                  it shall allocate a buffer for incoming NDEF message and
**                  pass the pointer within callback context. This buffer will be
**                  returned with NFA_SNEP_PUT_REQ_EVT after receiving complete
**                  NDEF message.  If buffer is not allocated, NFA_SNEP_RESP_CODE_REJECT
**                  will be sent to client or NFA will discard request and send
**                  NFA_SNEP_RESP_CODE_SUCCESS (Note:There is no proper response code for
**                  this case).
**
**                  Server application shall provide conn_handle which is received in
**                  NFA_SNEP_PUT_REQ_EVT.
**
**                  NFA_SNEP_DISC_EVT will be returned through registered callback
**                  function when client disconnects data link connection.
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_BAD_HANDLE if handle is not valid
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepPutResponse (tNFA_HANDLE         conn_handle,
                                 tNFA_SNEP_RESP_CODE resp_code)
{
    tNFA_SNEP_API_PUT_RESP *p_msg;
    tNFA_HANDLE            xx;

    SNEP_TRACE_API1 ("NFA_SnepPutResponse (): conn_handle:0x%X", conn_handle);

    xx = conn_handle & NFA_HANDLE_MASK;

    if (  (xx >= NFA_SNEP_MAX_CONN)
        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_SERVER))  )
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepPutResponse (): Handle is invalid");
        return (NFA_STATUS_BAD_HANDLE);
    }

    if ((p_msg = (tNFA_SNEP_API_PUT_RESP *) GKI_getbuf (sizeof (tNFA_SNEP_API_PUT_RESP))) != NULL)
    {
        p_msg->hdr.event = NFA_SNEP_API_PUT_RESP_EVT;

        p_msg->conn_handle = conn_handle;
        p_msg->resp_code   = resp_code;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepDisconnect
**
** Description      This function is called to disconnect data link connection.
**                  discard any pending data if flush is set to TRUE
**
**                  Client application shall provide conn_handle in NFA_SNEP_GET_RESP_EVT
**                  or NFA_SNEP_PUT_RESP_EVT.
**
**                  Server application shall provide conn_handle in NFA_SNEP_GET_REQ_EVT
**                  or NFA_SNEP_PUT_REQ_EVT.
**
**                  NFA_SNEP_DISC_EVT will be returned
**
** Returns          NFA_STATUS_OK if successfully initiated
**                  NFA_STATUS_BAD_HANDLE if handle is not valid
**                  NFA_STATUS_FAILED otherwise
**
*******************************************************************************/
tNFA_STATUS NFA_SnepDisconnect (tNFA_HANDLE conn_handle, BOOLEAN flush)
{
    tNFA_SNEP_API_DISCONNECT *p_msg;
    tNFA_HANDLE              xx;

    SNEP_TRACE_API2 ("NFA_SnepDisconnect (): conn_handle:0x%X, flush=%d", conn_handle, flush);

    xx = conn_handle & NFA_HANDLE_MASK;

    if (  (xx >= NFA_SNEP_MAX_CONN)
        ||(nfa_snep_cb.conn[xx].p_cback == NULL))
    {
        SNEP_TRACE_ERROR0 ("NFA_SnepDisconnect (): Handle is invalid");
        return (NFA_STATUS_BAD_HANDLE);
    }

    if ((p_msg = (tNFA_SNEP_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_SNEP_API_DISCONNECT))) != NULL)
    {
        p_msg->hdr.event   = NFA_SNEP_API_DISCONNECT_EVT;
        p_msg->conn_handle = conn_handle;
        p_msg->flush       = flush;

        nfa_sys_sendmsg (p_msg);

        return (NFA_STATUS_OK);
    }

    return (NFA_STATUS_FAILED);
}

/*******************************************************************************
**
** Function         NFA_SnepSetTraceLevel
**
** Description      This function sets the trace level for SNEP.  If called with
**                  a value of 0xFF, it simply returns the current trace level.
**
** Returns          The new or current trace level
**
*******************************************************************************/
UINT8 NFA_SnepSetTraceLevel (UINT8 new_level)
{
    if (new_level != 0xFF)
        nfa_snep_cb.trace_level = new_level;

    return (nfa_snep_cb.trace_level);
}