1e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/******************************************************************************
2e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
35c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  Copyright (C) 2010-2013 Broadcom Corporation
4e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
5e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
6e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  you may not use this file except in compliance with the License.
7e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  You may obtain a copy of the License at:
8e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
9e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
10e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
11e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  See the License for the specific language governing permissions and
15e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  limitations under the License.
16e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
17e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ******************************************************************************/
18e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
20e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/******************************************************************************
21e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
22e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  This file contains the implementation for Type 3 tag in Card Emulation
23e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  mode.
24e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
25e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ******************************************************************************/
26e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <string.h>
27e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "nfc_target.h"
28e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "bt_types.h"
29e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "trace_api.h"
30e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
31e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if (NFC_INCLUDED == TRUE)
32e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "nfc_api.h"
33e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "nfc_int.h"
34e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "ce_api.h"
35e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "ce_int.h"
36e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "tags_int.h"
37e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gki.h"
38e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
39e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectenum {
40e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_T3T_COMMAND_INVALID,
41e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_T3T_COMMAND_NFC_FORUM,
42e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_T3T_COMMAND_FELICA
43e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project};
44e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
45e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* T3T CE states */
46e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectenum {
47e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_T3T_STATE_NOT_ACTIVATED,
48e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_T3T_STATE_IDLE,
49e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_T3T_STATE_UPDATING
50e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project};
51e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
52e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Bitmasks to indicate type of UPDATE */
53e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#define CE_T3T_UPDATE_FL_NDEF_UPDATE_START  0x01
54e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#define CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT   0x02
55e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#define CE_T3T_UPDATE_FL_UPDATE             0x04
56e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
57e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
58e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project* Static constant definitions
59e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
60e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic const UINT8 CE_DEFAULT_LF_PMM[NCI_T3T_PMM_LEN] = {0x20, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};   /* Default PMm param */
61e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
62e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
63e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
64e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_init
65e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
66e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Initialize tag-specific fields of ce control block
67e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
68e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
69e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
70e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
71e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_init (void)
72e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
73e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memcpy (ce_cb.mem.t3t.local_pmm, CE_DEFAULT_LF_PMM, NCI_T3T_PMM_LEN);
74e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    ce_cb.mem.t3t.ndef_info.nbr = CE_T3T_DEFAULT_CHECK_MAXBLOCKS;
75e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    ce_cb.mem.t3t.ndef_info.nbw = CE_T3T_DEFAULT_UPDATE_MAXBLOCKS;
76e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
77e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
78e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
79e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
80e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_send_to_lower
81e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
82e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Send C-APDU to lower layer
83e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
84e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
85e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
86e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
87e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_send_to_lower (BT_HDR *p_msg)
88e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
89e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p;
90e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
91e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Set NFC-F SoD field (payload len + 1) */
92e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_msg->offset -= 1;         /* Point to SoD field */
93e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p = (UINT8 *) (p_msg+1) + p_msg->offset;
94e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8_TO_STREAM (p, (p_msg->len+1));
95e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_msg->len += 1;            /* Increment len to include SoD */
96e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
97e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if (BT_TRACE_PROTOCOL == TRUE)
98e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    DispT3TagMessage (p_msg, FALSE);
99e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif
100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (NFC_SendData (NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK)
102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR0 ("ce_t3t_send_to_lower (): NFC_SendData () failed");
104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_is_valid_opcode
110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Valid opcode
112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          Type of command
114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectUINT8 ce_t3t_is_valid_opcode (UINT8 cmd_id)
117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 retval = CE_T3T_COMMAND_INVALID;
119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (cmd_id == T3T_MSG_OPC_CHECK_CMD)
121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ||(cmd_id == T3T_MSG_OPC_UPDATE_CMD)  )
122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        retval = CE_T3T_COMMAND_NFC_FORUM;
124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else if (  (cmd_id == T3T_MSG_OPC_POLL_CMD)
126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project             ||(cmd_id == T3T_MSG_OPC_REQ_SERVICE_CMD)
127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project             ||(cmd_id == T3T_MSG_OPC_REQ_RESPONSE_CMD)
128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project             ||(cmd_id == T3T_MSG_OPC_REQ_SYSTEMCODE_CMD)  )
129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        retval = CE_T3T_COMMAND_FELICA;
131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (retval);
134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*****************************************************************************
137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_get_rsp_buf
139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Get a buffer for sending T3T messages
141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          BT_HDR *
143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*****************************************************************************/
145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectBT_HDR *ce_t3t_get_rsp_buf (void)
146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BT_HDR *p_cmd_buf;
148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID)) != NULL)
150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cmd_buf->len = 0;
154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (p_cmd_buf);
157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_send_rsp
162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Send response to reader/writer
164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_send_rsp (tCE_CB *p_ce_cb, UINT8 *p_nfcid2, UINT8 opcode, UINT8 status1, UINT8 status2)
169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BT_HDR *p_rsp_msg;
172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_dst, *p_rsp_start;
173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* If p_nfcid2 is NULL, then used activated NFCID2 */
175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_nfcid2 == NULL)
176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_nfcid2 = p_cb->local_nfcid2;
178e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
179e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
183e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Response Code */
185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, opcode);
186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Manufacturer ID */
188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ARRAY_TO_STREAM (p_dst, p_nfcid2, NCI_RF_F_UID_LEN);
189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Status1 and Status2 */
191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, status1);
192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, status2);
193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_t3t_send_to_lower (p_rsp_msg);
196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_handle_update_cmd
206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Handle UPDATE command from reader/writer
208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_handle_update_cmd (tCE_CB *p_ce_cb, BT_HDR *p_cmd_msg)
213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_temp;
216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_block_list = p_cb->cur_cmd.p_block_list_start;
217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_block_data = p_cb->cur_cmd.p_block_data_start;
218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 i, j, bl0;
219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16 block_number, service_code, checksum, checksum_rx;
220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT32 newlen_hiword;
221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_NDEF_INFO ndef_info;
222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS nfc_status = NFC_STATUS_OK;
223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 update_flags = 0;
224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_UPDATE_INFO update_info;
225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* If in idle state, notify app that update is starting */
227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_cb->state == CE_T3T_STATE_IDLE)
228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->state = CE_T3T_STATE_UPDATING;
230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Read byte0 of block list */
235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        STREAM_TO_UINT8 (bl0, p_block_list);
236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)
238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            STREAM_TO_UINT8 (block_number, p_block_list);
240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            STREAM_TO_UINT16 (block_number, p_block_list);
244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Read the block from memory */
247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        service_code = p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Reject UPDATE command if service code=T3T_MSG_NDEF_SC_RO */
250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (service_code == T3T_MSG_NDEF_SC_RO)
251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Error: invalid block number to update */
253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            CE_TRACE_ERROR0 ("CE: UPDATE request using read-only service");
254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            nfc_status = NFC_STATUS_FAILED;
255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Check for NDEF */
259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (service_code == T3T_MSG_NDEF_SC_RW)
260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbw)
262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                CE_TRACE_ERROR2 ("CE: Requested too many blocks to update (requested: %i, max: %i)", p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbw);
264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                nfc_status = NFC_STATUS_FAILED;
265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                CE_TRACE_ERROR0 ("CE: error: write-request to read-only NDEF message.");
270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                nfc_status = NFC_STATUS_FAILED;
271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (block_number == 0)
274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                CE_TRACE_DEBUG2 ("CE: Update sc 0x%04x block %i.", service_code, block_number);
276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Special caes: NDEF block0 is the ndef attribute block */
278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_temp = p_block_data;
279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                STREAM_TO_UINT8 (ndef_info.version, p_block_data);
280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_block_data+=8;                                    /* Ignore nbr,nbw,maxb,and reserved (reader/writer not allowed to update this) */
281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                STREAM_TO_UINT8 (ndef_info.writef, p_block_data);
282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_block_data++;                                     /* Ignore rwflag (reader/writer not allowed to update this) */
283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                STREAM_TO_UINT8 (newlen_hiword, p_block_data);
284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                BE_STREAM_TO_UINT16 (ndef_info.ln, p_block_data);
285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                ndef_info.ln += (newlen_hiword<<16);
286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                BE_STREAM_TO_UINT16 (checksum_rx, p_block_data);
287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                checksum=0;
289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                for (j=0; j<T3T_MSG_NDEF_ATTR_INFO_SIZE; j++)
290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    checksum+=p_temp[j];
292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Compare calcuated checksum with received checksum */
295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (checksum != checksum_rx)
296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    CE_TRACE_ERROR0 ("CE: Checksum failed for NDEF attribute block.");
298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    nfc_status = NFC_STATUS_FAILED;
299e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Update NDEF attribute block (only allowed to update current length and writef fields) */
303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_cb->ndef_info.scratch_ln      = ndef_info.ln;
304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_cb->ndef_info.scratch_writef  = ndef_info.writef;
305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* If writef=0 indicates completion of NDEF update */
307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (ndef_info.writef == 0)
308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT;
310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
311e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* writef=1 indicates start of NDEF update */
312e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    else
313e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
314e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_START;
315e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
316e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
317e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
318e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
319e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
320e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                CE_TRACE_DEBUG2 ("CE: Udpate sc 0x%04x block %i.", service_code, block_number);
321e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
322e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Verify that block_number is within NDEF memory */
323e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (block_number > p_cb->ndef_info.nmaxb)
324e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
325e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Error: invalid block number to update */
326e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    CE_TRACE_ERROR2 ("CE: Requested invalid NDEF block number to update %i (max is %i).", block_number, p_cb->ndef_info.nmaxb);
327e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    nfc_status = NFC_STATUS_FAILED;
328e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    break;
329e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
330e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
331e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
332e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Update NDEF memory block */
333e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    STREAM_TO_ARRAY ((&p_cb->ndef_info.p_scratch_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), p_block_data, T3T_MSG_BLOCKSIZE);
334e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
335e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
336e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Set flag to indicate that this UPDATE contained at least one block */
337e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                update_flags |= CE_T3T_UPDATE_FL_UPDATE;
338e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
339e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
340e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
341e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
342e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Error: invalid service code */
343e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            CE_TRACE_ERROR1 ("CE: Requested invalid service code: 0x%04x.", service_code);
344e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            nfc_status = NFC_STATUS_FAILED;
345e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
346e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
347e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
348e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
349e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Send appropriate response to reader/writer */
350e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (nfc_status == NFC_STATUS_OK)
351e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
352e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, T3T_MSG_RSP_STATUS_OK, T3T_MSG_RSP_STATUS_OK);
353e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
354e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
355e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
356e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, T3T_MSG_RSP_STATUS_ERROR, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
357e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->state = CE_T3T_STATE_IDLE;
358e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
359e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
360e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
361e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Notify the app of what got updated */
362e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_START)
363e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
364e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* NDEF attribute got updated with WriteF=TRUE */
365e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_ce_cb->p_cback (CE_T3T_NDEF_UPDATE_START_EVT, NULL);
366e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
367e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
368e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (update_flags & CE_T3T_UPDATE_FL_UPDATE)
369e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
370e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* UPDATE message contained at least one non-NDEF block */
371e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_ce_cb->p_cback (CE_T3T_UPDATE_EVT, NULL);
372e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
373e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
374e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
375e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT)
376e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
377e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* NDEF attribute got updated with WriteF=FALSE */
378e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        update_info.status = nfc_status;
379e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        update_info.p_data = p_cb->ndef_info.p_scratch_buf;
380e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        update_info.length = p_cb->ndef_info.scratch_ln;
381e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->state = CE_T3T_STATE_IDLE;
382e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_ce_cb->p_cback (CE_T3T_NDEF_UPDATE_CPLT_EVT, (tCE_DATA *) &update_info);
383e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
384e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
385e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    GKI_freebuf (p_cmd_msg);
386e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
387e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
388e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
389e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
390e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_handle_check_cmd
391e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
392e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Handle CHECK command from reader/writer
393e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
394e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          Nothing
395e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
396e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
397e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_handle_check_cmd (tCE_CB *p_ce_cb, BT_HDR *p_cmd_msg)
398e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
399e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
400e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BT_HDR *p_rsp_msg;
401e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_rsp_start;
402e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_dst, *p_temp, *p_status;
403e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_src = p_cb->cur_cmd.p_block_list_start;
404e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 i, bl0;
405e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 ndef_writef;
406e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT32 ndef_len;
407e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16 block_number, service_code, checksum;
408e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
409e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
410e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
411e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
412e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
413e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Response Code */
414e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_CHECK_RSP);
415e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
416e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Manufacturer ID */
417e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
418e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
419e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Save pointer to start of status field */
420e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_status = p_dst;
421e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
422e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Status1 and Status2 (assume success initially */
423e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_OK);
424e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_OK);
425e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, p_cb->cur_cmd.num_blocks);
426e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
427e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
428e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
429e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Read byte0 of block list */
430e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            STREAM_TO_UINT8 (bl0, p_src);
431e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
432e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)
433e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
434e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                STREAM_TO_UINT8 (block_number, p_src);
435e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
436e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
437e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
438e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                STREAM_TO_UINT16 (block_number, p_src);
439e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
440e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
441e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Read the block from memory */
442e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            service_code = p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
443e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
444e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Check for NDEF */
445e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if ((service_code == T3T_MSG_NDEF_SC_RO) || (service_code == T3T_MSG_NDEF_SC_RW))
446e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
447e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Verify Nbr (NDEF only) */
448e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbr)
449e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
450e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Error: invalid number of blocks to check */
451e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    CE_TRACE_ERROR2 ("CE: Requested too many blocks to check (requested: %i, max: %i)", p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbr);
452e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
453e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_dst = p_status;
454e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
455e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
456e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    break;
457e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
458e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else if (block_number == 0)
459e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
460e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Special caes: NDEF block0 is the ndef attribute block */
461e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_temp = p_dst;
462e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
463e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* For rw ndef, use scratch buffer's attributes (in case reader/writer had previously updated NDEF) */
464e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) && (p_cb->ndef_info.p_scratch_buf))
465e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
466e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        ndef_writef = p_cb->ndef_info.scratch_writef;
467e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        ndef_len    = p_cb->ndef_info.scratch_ln;
468e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
469e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    else
470e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
471e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        ndef_writef = p_cb->ndef_info.writef;
472e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        ndef_len    = p_cb->ndef_info.ln;
473e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
474e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
475e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.version);
476e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.nbr);
477e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.nbw);
478e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT16_TO_BE_STREAM (p_dst, p_cb->ndef_info.nmaxb);
479e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT32_TO_STREAM (p_dst, 0);
480e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, ndef_writef);
481e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.rwflag);
482e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT8_TO_STREAM (p_dst, (ndef_len >> 16 & 0xFF));
483e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT16_TO_BE_STREAM (p_dst, (ndef_len & 0xFFFF));
484e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
485e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    checksum = 0;
486e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
487e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
488e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        checksum+=p_temp[i];
489e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
490e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT16_TO_BE_STREAM (p_dst, checksum);
491e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
492e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
493e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
494e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Verify that block_number is within NDEF memory */
495e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (block_number > p_cb->ndef_info.nmaxb)
496e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
497e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Invalid block number */
498e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_dst = p_status;
499e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
500e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        CE_TRACE_ERROR1 ("CE: Requested block number to check %i.", block_number);
501e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
502e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Error: invalid number of blocks to check */
503e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
504e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
505e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        break;
506e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
507e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    else
508e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
509e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* If card is RW, then read from the scratch buffer (so reader/write can read back what it had just written */
510e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) && (p_cb->ndef_info.p_scratch_buf))
511e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
512e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            ARRAY_TO_STREAM (p_dst, (&p_cb->ndef_info.p_scratch_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), T3T_MSG_BLOCKSIZE);
513e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
514e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        else
515e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
516e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            ARRAY_TO_STREAM (p_dst, (&p_cb->ndef_info.p_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), T3T_MSG_BLOCKSIZE);
517e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
518e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
519e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
520e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
521e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
522e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
523e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Error: invalid service code */
524e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                CE_TRACE_ERROR1 ("CE: Requested invalid service code: 0x%04x.", service_code);
525e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
526e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_dst = p_status;
527e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
528e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
529e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
530e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
531e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
532e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
533e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
534e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_t3t_send_to_lower (p_rsp_msg);
535e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
536e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
537e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
538e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
539e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
540e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
541e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    GKI_freebuf (p_cmd_msg);
542e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
543e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
544e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
545e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
546e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
547e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_handle_non_nfc_forum_cmd
548e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
549e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Handle POLL command from reader/writer
550e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
551e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          Nothing
552e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
553e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
554e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_handle_non_nfc_forum_cmd (tCE_CB *p_mem_cb, UINT8 cmd_id, BT_HDR *p_cmd_msg)
555e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
556e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &p_mem_cb->mem.t3t;
557e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BT_HDR *p_rsp_msg;
558e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_rsp_start;
559e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_dst;
560e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p = (UINT8 *) (p_cmd_msg +1) + p_cmd_msg->offset;
561e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16 sc;
562e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 rc;
563e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN send_response = TRUE;
564e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
565e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
566e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
567e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
568e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
569e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        switch (cmd_id)
570e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
571e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case T3T_MSG_OPC_POLL_CMD:
572e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Get system code and RC */
573e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Skip over sod and cmd_id */
574e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p+=2;
575e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            BE_STREAM_TO_UINT16 (sc, p);
576e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            STREAM_TO_UINT8 (rc, p);
577e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
578e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* If requesting wildcard system code, or specifically our system code, then send POLL response */
579e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if ((sc == 0xFFFF) || (sc == p_cb->system_code))
580e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
581e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Response Code */
582e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_POLL_RSP);
583e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
584e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Manufacturer ID */
585e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
586e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
587e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Manufacturer Parameter PMm */
588e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                ARRAY_TO_STREAM (p_dst, p_cb->local_pmm, NCI_T3T_PMM_LEN);
589e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
590e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* If requesting system code */
591e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rc == T3T_POLL_RC_SC)
592e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
593e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    UINT16_TO_BE_STREAM (p_dst, p_cb->system_code);
594e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
595e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
596e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
597e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
598e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                send_response = FALSE;
599e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
600e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
601e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
602e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
603e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case T3T_MSG_OPC_REQ_RESPONSE_CMD:
604e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Response Code */
605e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_REQ_RESPONSE_RSP);
606e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
607e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Manufacturer ID */
608e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
609e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
610e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Mode */
611e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT8_TO_STREAM (p_dst, 0);
612e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
613e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
614e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case T3T_MSG_OPC_REQ_SYSTEMCODE_CMD:
615e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Response Code */
616e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_REQ_SYSTEMCODE_RSP);
617e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
618e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Manufacturer ID */
619e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
620e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
621e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Number of system codes */
622e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT8_TO_STREAM (p_dst, 1);
623e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
624e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* system codes */
625e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT16_TO_BE_STREAM (p_dst, T3T_SYSTEM_CODE_NDEF);
626e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
627e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
628e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
629e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case T3T_MSG_OPC_REQ_SERVICE_CMD:
630e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        default:
631e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Unhandled command */
632e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            CE_TRACE_ERROR1 ("Unhandled CE opcode: %02x", cmd_id);
633e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            send_response = FALSE;
634e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
635e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
636e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
637e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (send_response)
638e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
639e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
640e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ce_t3t_send_to_lower (p_rsp_msg);
641e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
642e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
643e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
644e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            GKI_freebuf (p_rsp_msg);
645e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
646e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
647e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
648e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
649e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
650e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
651e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    GKI_freebuf (p_cmd_msg);
652e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
653e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
654e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
655e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
656e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_data_cback
657e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
658e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This callback function receives the data from NFCC.
659e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
660e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
661e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
662e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
663e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_data_cback (UINT8 conn_id, BT_HDR *p_msg)
664e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
665e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_CB *p_ce_cb = &ce_cb;
666e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
667e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_DATA     ce_data;
668e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 cmd_id, bl0, entry_len, i;
669e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_nfcid2 = NULL;
670e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p = (UINT8 *) (p_msg +1) + p_msg->offset;
671e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 cmd_nfcid2[NCI_RF_F_UID_LEN];
672e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16 block_list_start_offset, remaining;
673e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN msg_processed = FALSE;
674e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN block_list_ok;
675e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 sod;
676e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 cmd_type;
677e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
678e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if (BT_TRACE_PROTOCOL == TRUE)
679e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    DispT3TagMessage (p_msg, TRUE);
680e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif
681e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
682e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* If activate system code is not NDEF, or if no local NDEF contents was set, then pass data up to the app */
683e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_cb->system_code != T3T_SYSTEM_CODE_NDEF) || (!p_cb->ndef_info.initialized))
684e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
685e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_data.raw_frame.status = NFC_STATUS_OK;
686e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_data.raw_frame.p_data = p_msg;
687e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_ce_cb->p_cback (CE_T3T_RAW_FRAME_EVT, &ce_data);
688e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return;
689e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
690e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
691e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Verify that message contains at least Sod and cmd_id */
692e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_msg->len < 2)
693e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
694e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid length: %i)", p_msg->len);
695e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
696e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
697e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
698e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
699e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Get and validate command opcode */
700e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        STREAM_TO_UINT8 (sod, p);
701e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        STREAM_TO_UINT8 (cmd_id, p);
702e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
703e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Valid command and message length */
704e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        cmd_type = ce_t3t_is_valid_opcode (cmd_id);
705e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (cmd_type == CE_T3T_COMMAND_INVALID)
706e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
707e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid command: 0x%02X)", cmd_id);
708e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
709e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else if (cmd_type == CE_T3T_COMMAND_FELICA)
710e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
711e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ce_t3t_handle_non_nfc_forum_cmd (p_ce_cb, cmd_id, p_msg);
712e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            msg_processed = TRUE;
713e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
714e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
715e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
716e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Verify that message contains at least NFCID2 and NUM services */
717e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_msg->len < T3T_MSG_CMD_COMMON_HDR_LEN)
718e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
719e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid length: %i)", p_msg->len);
720e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
721e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
722e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
723e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Handle NFC_FORUM command (UPDATE or CHECK) */
724e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                STREAM_TO_ARRAY (cmd_nfcid2, p, NCI_RF_F_UID_LEN);
725e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                STREAM_TO_UINT8 (p_cb->cur_cmd.num_services, p);
726e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
727e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Calculate offset of block-list-start */
728e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                block_list_start_offset = T3T_MSG_CMD_COMMON_HDR_LEN + 2*p_cb->cur_cmd.num_services + 1;
729e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
730e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (p_cb->state == CE_T3T_STATE_NOT_ACTIVATED)
731e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
732e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    CE_TRACE_ERROR2 ("CE: received command 0x%02X while in bad state (%i))", cmd_id, p_cb->state);
733e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
734e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else if (memcmp (cmd_nfcid2, p_cb->local_nfcid2, NCI_RF_F_UID_LEN) != 0)
735e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
736e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    CE_TRACE_ERROR0 ("CE: received invalid T3t message (invalid NFCID2)");
737e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_nfcid2 = cmd_nfcid2;      /* respond with ERROR using the NFCID2 from the command message */
738e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
739e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else if (p_msg->len < block_list_start_offset)
740e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
741e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Does not have minimum (including number_of_blocks field) */
742e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    CE_TRACE_ERROR0 ("CE: incomplete message");
743e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
744e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
745e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
746e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Parse service code list */
747e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    for (i = 0; i < p_cb->cur_cmd.num_services; i++)
748e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
749e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        STREAM_TO_UINT16 (p_cb->cur_cmd.service_code_list[i], p);
750e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
751e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
752e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Verify that block list */
753e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    block_list_ok = TRUE;
754e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    STREAM_TO_UINT8 (p_cb->cur_cmd.num_blocks, p);
755e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    remaining = p_msg->len - block_list_start_offset;
756e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_cb->cur_cmd.p_block_list_start = p;
757e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
758e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
759e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Each entry is at lease 2 bytes long */
760e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        if (remaining < 2)
761e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
762e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            /* Unexpected end of message (while reading block-list) */
763e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            CE_TRACE_ERROR0 ("CE: received invalid T3t message (unexpected end of block-list)");
764e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            block_list_ok = FALSE;
765e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            break;
766e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
767e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
768e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Get byte0 of block-list entry */
769e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        bl0 = *p;
770e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
771e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Validate service code index and size of block-list */
772e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        if ((bl0 & T3T_MSG_SERVICE_LIST_MASK) >= p_cb->cur_cmd.num_services)
773e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
774e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            /* Invalid service code */
775e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid service index: %i)", (bl0 & T3T_MSG_SERVICE_LIST_MASK));
776e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            block_list_ok = FALSE;
777e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            break;
778e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
779e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        else if ((!(bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)) && (remaining < 3))
780e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
781e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            /* Unexpected end of message (while reading 3-byte entry) */
782e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            CE_TRACE_ERROR0 ("CE: received invalid T3t message (unexpected end of block-list)");
783e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            block_list_ok = FALSE;
784e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            break;
785e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
786e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
787e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Advance pointers to next block-list entry */
788e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        entry_len = (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT) ? 2 : 3;
789e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p+=entry_len;
790e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        remaining-=entry_len;
791e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
792e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
793e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Block list is verified. Call CHECK or UPDATE handler */
794e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (block_list_ok)
795e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
796e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_cb->cur_cmd.p_block_data_start = p;
797e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        if (cmd_id == T3T_MSG_OPC_CHECK_CMD)
798e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
799e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            /* This is a CHECK command. Sanity check: there shouldn't be any more data remaining after reading block list */
800e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            if (remaining)
801e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            {
802e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                CE_TRACE_ERROR1 ("CE: unexpected data after after CHECK command (#i bytes)", remaining);
803e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            }
804e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            ce_t3t_handle_check_cmd (p_ce_cb, p_msg);
805e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            msg_processed = TRUE;
806e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
807e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        else
808e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
809e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            /* This is an UPDATE command. See if message contains all the expected block data */
810e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            if (remaining < p_cb->cur_cmd.num_blocks*T3T_MSG_BLOCKSIZE)
811e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            {
812e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                CE_TRACE_ERROR0 ("CE: unexpected end of block-data");
813e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            }
814e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            else
815e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            {
816e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                ce_t3t_handle_update_cmd (p_ce_cb, p_msg);
817e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                msg_processed = TRUE;
818e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            }
819e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
820e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
821e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
822e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
823e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
824e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
825e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
826e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!msg_processed)
827e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
828e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_t3t_send_rsp (p_ce_cb, p_nfcid2, T3T_MSG_OPC_CHECK_RSP, T3T_MSG_RSP_STATUS_ERROR, T3T_MSG_RSP_STATUS2_ERROR_PROCESSING);
829e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        GKI_freebuf (p_msg);
830e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
831e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
832e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
833e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
834e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
835e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
836e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
837e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_t3t_conn_cback
838e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
839e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This callback function receives the events/data from NFCC.
840e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
841e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
842e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
843e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
844e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ce_t3t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
845e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
846e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
847e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
848e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_TRACE_DEBUG2 ("ce_t3t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
849e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
850e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    switch (event)
851e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
852e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case NFC_CONN_CREATE_CEVT:
853e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
854e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
855e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case NFC_CONN_CLOSE_CEVT:
856e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->state = CE_T3T_STATE_NOT_ACTIVATED;
857e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
858e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
859e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case NFC_DATA_CEVT:
860e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_data->data.status == NFC_STATUS_OK)
861e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
862e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ce_t3t_data_cback (conn_id, p_data->data.p_data);
863e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
864e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
865e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
866e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case NFC_DEACTIVATE_CEVT:
867e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->state = CE_T3T_STATE_NOT_ACTIVATED;
868e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        NFC_SetStaticRfCback (NULL);
869e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
870e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
871e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    default:
872e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
873e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
874e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
875e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
876e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
877e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
878e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
879e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         ce_select_t3t
880e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
881e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Select Type 3 Tag
882e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
883e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NFC_STATUS_OK if success
884e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
885e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
886e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS ce_select_t3t (UINT16 system_code, UINT8 nfcid2[NCI_RF_F_UID_LEN])
887e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
888e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
889e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
890e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_TRACE_DEBUG0 ("ce_select_t3t ()");
891e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
892e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_cb->state = CE_T3T_STATE_IDLE;
893e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_cb->system_code = system_code;
894e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memcpy (p_cb->local_nfcid2, nfcid2, NCI_RF_F_UID_LEN);
895e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
896e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    NFC_SetStaticRfCback (ce_t3t_conn_cback);
897e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return NFC_STATUS_OK;
898e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
899e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
900e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
901e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
902e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
903e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         CE_T3tSetLocalNDEFMsg
904e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
905e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Initialise CE Type 3 Tag with mandatory NDEF message
906e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
907e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NFC_STATUS_OK if success
908e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
909e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
910e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS CE_T3tSetLocalNDEFMsg (BOOLEAN read_only,
911e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                   UINT32  size_max,
912e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                   UINT32  size_current,
913e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                   UINT8   *p_buf,
914e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                   UINT8   *p_scratch_buf)
915e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
916e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
917e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
918e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_TRACE_API3 ("CE_T3tSetContent: ro=%i, size_max=%i, size_current=%i", read_only, size_max, size_current);
919e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
920e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Verify scratch buffer was provided if NDEF message is read/write */
921e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((!read_only) && (!p_scratch_buf))
922e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
923e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR0 ("CE_T3tSetLocalNDEFMsg (): p_scratch_buf cannot be NULL if not read-only");
924e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return NFC_STATUS_FAILED;
925e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
926e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
927e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Check if disabling the local NDEF */
928e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!p_buf)
929e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
930e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.initialized = FALSE;
931e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
932e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Save ndef attributes */
933e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
934e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
935e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.initialized = TRUE;
936e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.ln = size_current;                          /* Current length */
937e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.nmaxb = (UINT16) ((size_max + 15) / T3T_MSG_BLOCKSIZE);  /* Max length (in blocks) */
938e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.rwflag = (read_only) ? T3T_MSG_NDEF_RWFLAG_RO : T3T_MSG_NDEF_RWFLAG_RW;
939e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.writef = T3T_MSG_NDEF_WRITEF_OFF;
940e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.version = 0x10;
941e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.p_buf = p_buf;
942e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_cb->ndef_info.p_scratch_buf = p_scratch_buf;
943e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
944e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Initiate scratch buffer with same contents as read-buffer */
945e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_scratch_buf)
946e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
947e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_cb->ndef_info.scratch_ln      = p_cb->ndef_info.ln;
948e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_cb->ndef_info.scratch_writef  = T3T_MSG_NDEF_WRITEF_OFF;
949e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            memcpy (p_scratch_buf, p_buf, p_cb->ndef_info.ln);
950e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
951e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
952e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
953e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (NFC_STATUS_OK);
954e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
955e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
956e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
957e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
958e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         CE_T3tSetLocalNDefParams
959e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
960e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Sets T3T-specific NDEF parameters. (Optional - if not
961e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  called, then CE will use default parameters)
962e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
963e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NFC_STATUS_OK if success
964e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
965e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
966e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS CE_T3tSetLocalNDefParams (UINT8 nbr, UINT8 nbw)
967e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
968e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
969e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
970e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_TRACE_API2 ("CE_T3tSetLocalNDefParams: nbr=%i, nbw=%i", nbr, nbw);
971e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
972e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Validate */
973e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((nbr > T3T_MSG_NUM_BLOCKS_CHECK_MAX) || (nbw>T3T_MSG_NUM_BLOCKS_UPDATE_MAX) || (nbr < 1) || (nbw < 1))
974e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
975e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR0 ("CE_T3tSetLocalNDefParams: invalid params");
976e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return NFC_STATUS_FAILED;
977e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
978e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
979e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_cb->ndef_info.nbr = nbr;
980e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_cb->ndef_info.nbw = nbw;
981e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
982e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return NFC_STATUS_OK;
983e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
984e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
985e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
986e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
987e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         CE_T3tSendCheckRsp
988e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
989e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Send CHECK response message
990e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
991e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NFC_STATUS_OK if success
992e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
993e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
994e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS CE_T3tSendCheckRsp (UINT8 status1, UINT8 status2, UINT8 num_blocks, UINT8 *p_block_data)
995e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
996e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
997e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS retval = NFC_STATUS_OK;
998e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BT_HDR *p_rsp_msg;
999e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8 *p_dst, *p_rsp_start;
1000e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1001e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_TRACE_API3 ("CE_T3tCheckRsp: status1=0x%02X, status2=0x%02X, num_blocks=%i", status1, status2, num_blocks);
1002e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1003e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Validate num_blocks */
1004e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (num_blocks > T3T_MSG_NUM_BLOCKS_CHECK_MAX)
1005e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1006e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR2 ("CE_T3tCheckRsp num_blocks (%i) exceeds maximum (%i)", num_blocks, T3T_MSG_NUM_BLOCKS_CHECK_MAX);
1007e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
1008e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1009e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1010e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
1011e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1012e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
1013e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1014e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Response Code */
1015e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_CHECK_RSP);
1016e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1017e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Manufacturer ID */
1018e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
1019e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1020e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Status1 and Status2 */
1021e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, status1);
1022e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_STREAM (p_dst, status2);
1023e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1024e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (status1 == T3T_MSG_RSP_STATUS_OK)
1025e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1026e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT8_TO_STREAM (p_dst, num_blocks);
1027e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ARRAY_TO_STREAM (p_dst, p_block_data, (num_blocks * T3T_MSG_BLOCKSIZE));
1028e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1029e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1030e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
1031e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ce_t3t_send_to_lower (p_rsp_msg);
1032e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1033e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1034e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1035e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        CE_TRACE_ERROR0 ("CE: Unable to allocate buffer for response message");
1036e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1037e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1038e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (retval);
1039e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1040e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1041e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1042e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1043e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         CE_T3tSendUpdateRsp
1044e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1045e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Send UPDATE response message
1046e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1047e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NFC_STATUS_OK if success
1048e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1049e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1050e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS CE_T3tSendUpdateRsp (UINT8 status1, UINT8 status2)
1051e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1052e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS retval = NFC_STATUS_OK;
1053e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tCE_CB *p_ce_cb = &ce_cb;
1054e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1055e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    CE_TRACE_API2 ("CE_T3tUpdateRsp: status1=0x%02X, status2=0x%02X", status1, status2);
1056e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, status1, status2);
1057e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1058e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (retval);
1059e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1060e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1061e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif /* NFC_INCLUDED == TRUE */
1062