blob: 07f3061b6c30c9406a0647bf2ab0afec07760191 [file] [log] [blame]
/******************************************************************************
*
* 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;
}