1e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/******************************************************************************
2e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *
3e9629bad30a9f478b336ab46b8e6e02f7f87af46Evan Chu *  Copyright (C) 2010-2014 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 2 tag NDEF operation in
23e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *  Reader/Writer 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
29e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if (NFC_INCLUDED == TRUE)
30e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "nfc_api.h"
31e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "nci_hmsgs.h"
32e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "rw_api.h"
33e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "rw_int.h"
34e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "nfc_int.h"
35e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gki.h"
36e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
37e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
38e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
39e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Local static functions */
40e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_cc_read_rsp (void);
41e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_lock_read_rsp (UINT8 *p_data);
42e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data);
43e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data);
44e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data);
45e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_format_tag_rsp (UINT8 *p_data);
46e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_config_tag_readonly (UINT8 *p_data);
47e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic UINT8 rw_t2t_get_tag_size (UINT8 *p_data);
48e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_extract_default_locks_info (void);
49e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len);
50e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic UINT8 rw_t2t_get_ndef_flags (void);
51e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic UINT16 rw_t2t_get_ndef_max_size (void);
52e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_read_locks (void);
53e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_read_ndef_last_block (void);
54e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_update_attributes (void);
55e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_update_lock_attributes (void);
56e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index);
57e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic BOOLEAN rw_t2t_is_read_only_byte (UINT16 index);
58e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len);
59e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len);
60e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block);
61e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_add_terminator_tlv (void);
62e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read);
63e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_set_cc (UINT8 tms);
64e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size);
65e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_format_tag (void);
66e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_soft_lock_tag (void);
67e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic tNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data);
68e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status);
69e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
70e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectconst UINT8 rw_t2t_mask_bits[8] =
71e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
72e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
73e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
74e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
75e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_rsp
76e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
77e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function handles response to command sent during
78e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NDEF and other tlv operation
79e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
80e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          None
81e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
82e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
83e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid rw_t2t_handle_rsp (UINT8 *p_data)
84e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
85e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
86e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
87e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
88e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
89e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->b_read_hdr = TRUE;
90e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->tag_hdr,  p_data, T2T_READ_DATA_LEN);
91e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
92e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
93e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    switch (p_t2t->state)
94e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
95e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_DETECT_TLV:
96e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV)
97e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
98e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
99e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_handle_cc_read_rsp ();
101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_handle_lock_read_rsp (p_data);
105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_handle_tlv_detect_rsp (p_data);
109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else if (p_t2t->tlv_detect == TAG_NDEF_TLV)
112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] == T2T_CC0_NMN)
116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    rw_t2t_handle_cc_read_rsp ();
118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    RW_TRACE_WARNING3 ("NDEF Detection failed!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: 0x%02x", p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE], p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_handle_lock_read_rsp (p_data);
128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_handle_tlv_detect_rsp (p_data);
132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_handle_cc_read_rsp ();
139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_handle_tlv_detect_rsp (p_data);
143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_SET_TAG_RO:
148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_config_tag_readonly (p_data);
149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_FORMAT_TAG:
152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_format_tag_rsp (p_data);
153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_READ_NDEF:
156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_ndef_read_rsp (p_data);
157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_WRITE_NDEF:
160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_ndef_write_rsp (p_data);
161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_info_to_event
168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function returns RW event code based on the current state
170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          RW event code
172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttRW_EVENT rw_t2t_info_to_event (const tT2T_CMD_RSP_INFO *p_info)
175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_EVENT   rw_event;
177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
178e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
179e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    switch (p_t2t->state)
180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_DETECT_TLV:
182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->tlv_detect == TAG_NDEF_TLV)
183e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            rw_event = RW_T2T_NDEF_DETECT_EVT;
184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            rw_event = RW_T2T_TLV_DETECT_EVT;
186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_READ_NDEF:
190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_event = RW_T2T_NDEF_READ_EVT;
191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_WRITE_NDEF:
194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_event = RW_T2T_NDEF_WRITE_EVT;
195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_SET_TAG_RO:
198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_event = RW_T2T_SET_TAG_RO_EVT;
199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_CHECK_PRESENCE:
202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_event = RW_T2T_PRESENCE_CHECK_EVT;
203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_STATE_FORMAT_TAG:
206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_event = RW_T2T_FORMAT_CPLT_EVT;
207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    default:
210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project	    rw_event = t2t_info_to_evt (p_info);
211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return rw_event;
214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_cc_read_rsp
219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Handle read cc bytes
221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_cc_read_rsp (void)
226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (  (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           &&(p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RO)  )
231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                                    ||
232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project          (  (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO)
233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           &&(p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO)
234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           &&(p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO)  )  )
235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Invalid Version number or RWA byte */
237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return;
239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (rw_t2t_read ((UINT16) T2T_FIRST_DATA_BLOCK) != NFC_STATUS_OK)
244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_ntf_tlv_detect_complete
252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Notify TLV detection complete to upper layer
254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status)
259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_DETECT_NDEF_DATA    ndef_data = {0};
262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_DETECT_TLV_DATA     tlv_data;
263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_DETECT          evt_data;
264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   xx;
265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->tlv_detect == TAG_NDEF_TLV)
267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Notify upper layer the result of NDEF detect op */
269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ndef_data.status    = status;
270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ndef_data.protocol  = NFC_PROTOCOL_T2T;
271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ndef_data.flags     = rw_t2t_get_ndef_flags ();
272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ndef_data.cur_size  = p_t2t->ndef_msg_len;
273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (status == NFC_STATUS_OK)
275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ndef_data.flags   |= RW_NDEF_FL_FORMATED;
276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] == T2T_CC3_RWA_RW)
278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ndef_data.max_size = (UINT32) rw_t2t_get_ndef_max_size ();
279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ndef_data.max_size = ndef_data.cur_size;
281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (ndef_data.max_size < ndef_data.cur_size)
283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ndef_data.flags   |= RW_NDEF_FL_READ_ONLY;
285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ndef_data.max_size = ndef_data.cur_size;
286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ndef_data.flags  |= RW_NDEF_FL_SOFT_LOCKABLE;
291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (status == NFC_STATUS_OK)
292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_op_complete ();
296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        (*rw_cb.p_cback) (RW_T2T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else if (p_t2t->tlv_detect == TAG_PROPRIETARY_TLV)
299e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt_data.msg_len = p_t2t->prop_msg_len;
301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt_data.status  = status;
302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_op_complete ();
303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &evt_data);
304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Notify upper layer the result of Lock/Mem TLV detect op */
308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        tlv_data.protocol   = NFC_PROTOCOL_T2T;
309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV)
310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
311e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            tlv_data.num_bytes  = p_t2t->num_lockbytes;
312e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
313e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
314e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
315e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            tlv_data.num_bytes = 0;
316e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
317e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
318e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                tlv_data.num_bytes += p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes;
319e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
320e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
321e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        tlv_data.status     = status;
322e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_op_complete ();
323e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
324e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
325e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
326e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
327e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
328e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
329e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
330e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_lock_read_rsp
331e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
332e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Handle response to reading lock bytes
333e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
334e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
335e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
336e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
337e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_lock_read_rsp (UINT8 *p_data)
338e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
339e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   updated_lock_byte;
340e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   num_locks;
341e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   offset = 0;
342e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16                  lock_offset;
343e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16                  base_lock_offset = 0;
344e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
345e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16                  block;
346e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
347e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Prepare NDEF/TLV attributes (based on current op) for sending response to upper layer */
348e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
349e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    num_locks = 0;
350e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    updated_lock_byte = 0;
351e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
352e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /*  Extract all lock bytes present in the read 16 bytes
353e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     *  but atleast one lock byte (base lock) should be present in the read 16 bytes */
354e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
355e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (num_locks < p_t2t->num_lockbytes)
356e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
357e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->lockbyte[num_locks].b_lock_read == FALSE)
358e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
359e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            lock_offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
360e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (updated_lock_byte == 0)
361e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
362e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* The offset of the first lock byte present in the 16 bytes read using READ command */
363e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                base_lock_offset = lock_offset;
364e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Block number used to read may not be the block where lock offset is present */
365e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                offset = (UINT8) (lock_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
366e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Update the lock byte value in the control block */
367e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->lockbyte[num_locks].lock_byte = p_data[offset];
368e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
369e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                updated_lock_byte++;
370e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
371e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (lock_offset > base_lock_offset)
372e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
373e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Atleast one lock byte will get updated in the control block */
374e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if ((lock_offset - base_lock_offset + offset) < T2T_READ_DATA_LEN)
375e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
376e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* And this lock byte is also present in the read data */
377e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->lockbyte[num_locks].lock_byte   = p_data[lock_offset - base_lock_offset + offset];
378e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
379e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    updated_lock_byte++;
380e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
381e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
382e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
383e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* This lock byte is not present in the read data */
384e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    block  = (UINT16) (lock_offset / T2T_BLOCK_LEN);
385e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    block -= block % T2T_READ_BLOCKS;
386e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* send READ command to read this lock byte */
387e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (NFC_STATUS_OK != rw_t2t_read ((UINT16) block))
388e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
389e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Unable to send Read command, notify failure status to upper layer */
390e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
391e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
392e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    break;
393e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
394e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
395e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
396e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
397e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* This Lock byte is not present in the read 16 bytes
398e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                 * send READ command to read the lock byte       */
399e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (NFC_STATUS_OK != rw_t2t_read ((UINT16) (lock_offset / T2T_BLOCK_LEN)))
400e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
401e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Unable to send Read command, notify failure status to upper layer */
402e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
403e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
404e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
405e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
406e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
407e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_locks++;
408e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
409e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (num_locks == p_t2t->num_lockbytes)
410e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
411e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* All locks are read, notify upper layer */
412e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_update_lock_attributes ();
413e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_OK);
414e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
415e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
416e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
417e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
418e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
419e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_tlv_detect_rsp
420e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
421e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Handle TLV detection.
422e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
423e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
424e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
425e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
426e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data)
427e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
428e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB              *p_t2t = &rw_cb.tcb.t2t;
429e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16                  offset;
430e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16                  len = 0;
431e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN                 failed = FALSE;
432e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN                 found  = FALSE;
433e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_EVENT               event;
434e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   index;
435e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   count = 0;
436e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   xx;
437e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS             status;
438e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tT2T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
439e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8                   tlvtype = p_t2t->tlv_detect;
440e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
441e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->work_offset == 0)
442e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
443e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Skip UID,Static Lock block,CC*/
444e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->work_offset = T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN;
445e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->b_read_data = TRUE;
446e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->tag_data,  p_data, T2T_READ_DATA_LEN);
447e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
448e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
449e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->segment = 0;
450e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
451e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    for (offset = 0; offset < T2T_READ_DATA_LEN  && !failed && !found;)
452e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
453e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_is_lock_res_byte ((UINT16) (p_t2t->work_offset + offset)) == TRUE)
454e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
455e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Skip locks, reserved bytes while searching for TLV */
456e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset++;
457e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            continue;
458e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
459e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        switch (p_t2t->substate)
460e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
461e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
462e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Search for the tlv */
463e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->found_tlv = p_data[offset++];
464e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            switch (p_t2t->found_tlv)
465e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
466e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_NULL_TLV:         /* May be used for padding. SHALL ignore this */
467e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
468e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
469e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_NDEF_TLV:
470e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (tlvtype == TAG_NDEF_TLV)
471e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
472e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* NDEF Detected, now collect NDEF Attributes including NDEF Length */
473e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    index = (offset % T2T_BLOCK_SIZE);
474e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Backup ndef first block */
475e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    memcpy (p_t2t->ndef_first_block,&p_data[offset-index],index);
476e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
477e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
478e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else if (tlvtype == TAG_PROPRIETARY_TLV)
479e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
480e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Proprietary TLV can exist after NDEF Tlv so we continue searching */
481e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
482e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
483e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
484e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                         ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
485e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
486e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Lock / Memory control tlv cannot exist after NDEF TLV
487e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                     * So when NDEF is found, we stop searching for Lock and Memory control tlv */
488e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    found = TRUE;
489e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
490e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
491e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
492e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* While searching for Lock / Memory control tlv, if NDEF TLV is found
493e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                     * first then our search for Lock /Memory control tlv failed and we stop here */
494e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    failed = TRUE;
495e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
496e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
497e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
498e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_LOCK_CTRL_TLV:
499e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_MEM_CTRL_TLV:
500e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
501e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
502e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
503e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_PROPRIETARY_TLV:
504e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (tlvtype == TAG_PROPRIETARY_TLV)
505e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
506e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    index = (offset % T2T_BLOCK_SIZE);
507e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
508e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
509e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
510e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
511c11a054fc2855196292b062a843321121b591cc0Evan Chu                    /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we continue searching, skiping proprietary tlv */
512c11a054fc2855196292b062a843321121b591cc0Evan Chu                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
513e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
514e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
515e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
516e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_TERMINATOR_TLV:   /* Last TLV block in the data area. Must be no NDEF nessage */
517e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
518e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
519e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
520e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* No more Lock/Memory TLV control tlv in the tag, so stop searching */
521e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    found = TRUE;
522e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
523e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
524e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
525e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* NDEF/Lock/Memory/Proprietary TLV cannot exist after Terminator Tlv */
526e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    failed = TRUE;
527e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
528e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
529e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            default:
530e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
531e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
532e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
533e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
534e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
535e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            len = p_data[offset];
536e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            switch (p_t2t->found_tlv)
537e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
538e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_NDEF_TLV:
539e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->ndef_header_offset = offset + p_t2t->work_offset;
540e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (len == TAG_LONG_NDEF_LEN_FIELD_BYTE0)
541e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
542e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* The next two bytes constitute length bytes */
543e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
544e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
545e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
546e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
547e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* one byte length field */
548e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->ndef_msg_len = len;
549e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->bytes_count  = p_t2t->ndef_msg_len;
550e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
551e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
552e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
553e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
554e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_PROPRIETARY_TLV:
555e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (len == T2T_LONG_NDEF_LEN_FIELD_BYTE0)
556e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
557e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* The next two bytes constitute length bytes */
558e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
559e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
560e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
561e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
562e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* one byte length field */
563e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->prop_msg_len = len;
564e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->bytes_count  = p_t2t->prop_msg_len;
565e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
566e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
567e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
568e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
569e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset++;
570e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
571e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
572e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
573e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            switch (p_t2t->found_tlv)
574e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
575e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_LOCK_CTRL_TLV:
576e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_MEM_CTRL_TLV:
577e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
578e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                len = p_data[offset];
579e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (len == TAG_DEFAULT_TLV_LEN)
580e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
581e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Valid Lock control TLV */
582e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
583e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->bytes_count = TAG_DEFAULT_TLV_LEN;
584e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
585e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
586e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                         ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
587e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
588e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Stop searching for Lock/ Memory control tlv */
589e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    found = TRUE;
590e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
591e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
592e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
593e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    failed = TRUE;
594e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
595e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
596e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
597e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_NDEF_TLV:
598e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_PROPRIETARY_TLV:
599e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* The first length byte */
600e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->bytes_count  = (UINT8) p_data[offset];
601e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1;
602e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
603e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
604e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset++;
605e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
606e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
607e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
608e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Prepare NDEF Message length */
609e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->bytes_count  = (p_t2t->bytes_count << 8) + p_data[offset];
610e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->found_tlv == TAG_NDEF_TLV)
611e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
612e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->ndef_msg_len = p_t2t->bytes_count;
613e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
614e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (p_t2t->found_tlv == TAG_PROPRIETARY_TLV)
615e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
616e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->prop_msg_len = p_t2t->bytes_count;
617e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
618e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
619e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset++;
620e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
621e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
622e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
623e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            switch (p_t2t->found_tlv)
624e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
625e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_NDEF_TLV:
626e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (  (p_t2t->bytes_count == p_t2t->ndef_msg_len)
627e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    &&(tlvtype == TAG_NDEF_TLV)  )
628e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
629e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* The first byte offset after length field */
630e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->ndef_msg_offset = offset + p_t2t->work_offset;
631e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
632e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Reduce number of NDEF bytes remaining to pass over NDEF TLV */
633e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (p_t2t->bytes_count > 0)
634e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->bytes_count--;
635e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
636e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (tlvtype == TAG_NDEF_TLV)
637e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
638e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    found = TRUE;
639e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->ndef_status = T2T_NDEF_DETECTED;
640e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
641e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else if (p_t2t->bytes_count == 0)
642e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
643e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Next byte could be a different TLV */
644e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
645e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
646e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
647e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
648e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_LOCK_CTRL_TLV:
649e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->bytes_count--;
650e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (  (tlvtype == TAG_LOCK_CTRL_TLV)
651e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    ||(tlvtype == TAG_NDEF_TLV)  )
652e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
653e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Collect Lock TLV */
654e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
655e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (p_t2t->bytes_count == 0)
656e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
657e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Lock TLV is collected and buffered in tlv_value, now decode it */
658e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset   = (p_t2t->tlv_value[0] >> 4) & 0x0F;
659e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset  *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F);
660e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset  += p_t2t->tlv_value[0] & 0x0F;
661e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
662e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = p_t2t->tlv_value[1];
663e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        count = p_t2t->tlv_value[1] / 8 + ((p_t2t->tlv_value[1]%8 != 0)? 1:0);
664e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
665e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Extract lockbytes info addressed by this Lock TLV */
666e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        xx = 0;
667e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        while (xx < count)
668e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
669e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index     = p_t2t->num_lock_tlvs;
670e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index    = xx;
671e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read   = FALSE;
672e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            xx++;
673e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->num_lockbytes++;
674e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
675e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->num_lock_tlvs++;
676e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        rw_t2t_update_attributes ();
677e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Next byte could be a different TLV */
678e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
679e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
680e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
681e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
682e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
683e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* If not looking for lock/ndef tlv, just skip this Lock TLV */
684e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (p_t2t->bytes_count == 0)
685e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
686e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
687e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
688e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
689e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
690e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
691e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_MEM_CTRL_TLV:
692e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->bytes_count--;
693e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (  (tlvtype == TAG_MEM_CTRL_TLV)
694e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    ||(tlvtype == TAG_NDEF_TLV)  )
695e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
696e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
697e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (p_t2t->bytes_count == 0)
698e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
699e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS)
700e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
701e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            RW_TRACE_ERROR0 ("rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached");
702e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            failed  = TRUE;
703e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
704e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        else
705e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        {
706e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            /* Extract memory control tlv */
707e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset    = (p_t2t->tlv_value[0] >> 4) & 0x0F;
708e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset   *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F);
709e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset   += p_t2t->tlv_value[0] & 0x0F;
710e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes = p_t2t->tlv_value[1];
711e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->num_mem_tlvs++;
712e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            rw_t2t_update_attributes ();
713e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
714e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        }
715e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
716e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
717e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
718e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
719e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (p_t2t->bytes_count == 0)
720e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
721e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
722e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
723e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
724e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
725e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
726e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            case TAG_PROPRIETARY_TLV:
727e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->bytes_count--;
728e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (tlvtype == TAG_PROPRIETARY_TLV)
729e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
730e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    found = TRUE;
731e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->prop_msg_len = len;
732e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
733e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
734e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
735e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (p_t2t->bytes_count == 0)
736e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
737e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
738e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
739e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
740e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
741e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
742e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset++;
743e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
744e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
745e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
746e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
747e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
748e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->work_offset += T2T_READ_DATA_LEN;
749e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
750e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    event = rw_t2t_info_to_event (p_cmd_rsp_info);
751e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
752e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* If not found and not failed, read next block and search tlv */
753e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!found && !failed)
754e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
755e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
756e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->work_offset >= (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR))
757e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
758e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
759e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
760e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
761e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                found = TRUE;
762e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
763e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
764e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
765e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
766e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
767e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
768e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
769e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
770e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_read ((UINT16) ((p_t2t->work_offset / T2T_BLOCK_LEN) + T2T_FIRST_DATA_BLOCK)) != NFC_STATUS_OK)
771e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
772e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
773e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
774e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
775e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (failed || found)
776e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
777e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (tlvtype == TAG_LOCK_CTRL_TLV)
778e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
779e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Incase no Lock control tlv is present then look for default dynamic lock bytes */
780e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            rw_t2t_extract_default_locks_info ();
781e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
782e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Send command to read the dynamic lock bytes */
783e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            status = rw_t2t_read_locks ();
784e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
785e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (status != NFC_STATUS_CONTINUE)
786e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
787e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* If unable to read a lock/all locks read, notify upper layer */
788e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_update_lock_attributes ();
789e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_ntf_tlv_detect_complete (status);
790e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
791e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
792e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else if (tlvtype == TAG_NDEF_TLV)
793e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
794e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            rw_t2t_extract_default_locks_info ();
795e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
796e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (failed)
797e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
798e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
799e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
800e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
801e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
802e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* NDEF present,Send command to read the dynamic lock bytes */
803e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                status = rw_t2t_read_locks ();
804e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (status != NFC_STATUS_CONTINUE)
805e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
806e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* If unable to read a lock/all locks read, notify upper layer */
807e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    rw_t2t_update_lock_attributes ();
808e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    rw_t2t_ntf_tlv_detect_complete (status);
809e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
810e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
811e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
812e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
813e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
814e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Notify Memory/ Proprietary tlv detect result */
815e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            status  = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
816e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            rw_t2t_ntf_tlv_detect_complete (status);
817e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
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** Function         rw_t2t_read_locks
824e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
825e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will send command to read next unread locks
826e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
827e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NFC_STATUS_OK, if all locks are read successfully
828e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_FAILED, if reading locks failed
829e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_CONTINUE, if reading locks is in progress
830e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
831e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
832e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_read_locks (void)
833e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
834e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_locks   = 0;
835e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t      = &rw_cb.tcb.t2t;
836e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status      = NFC_STATUS_CONTINUE;
837e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      offset;
838e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      block;
839e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
840e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
841c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu        ||(p_t2t->skip_dyn_locks)  )
842e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
843c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu        /* Skip reading dynamic lock bytes if CC is set as Read only or layer above instructs to skip */
844e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (num_locks < p_t2t->num_lockbytes)
845e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
846e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->lockbyte[num_locks].lock_byte   = 0x00;
847e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
848e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_locks++;
849e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
850e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
851e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
852e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (num_locks < p_t2t->num_lockbytes)
853e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
854e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->lockbyte[num_locks].b_lock_read == FALSE)
855e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
856e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Send Read command to read the first un read locks */
857e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
858e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
859e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Read 16 bytes where this lock byte is present */
860e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            block  = (UINT16) (offset / T2T_BLOCK_LEN);
861e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            block -= block % T2T_READ_BLOCKS;
862e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
863e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS;
864e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* send READ8 command */
865e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK)
866e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
867e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Reading Locks */
868e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                status          = NFC_STATUS_CONTINUE;
869e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
870e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
871e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
872e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                status = NFC_STATUS_FAILED;
873e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
874e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
875e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
876e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_locks++;
877e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
878e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (num_locks == p_t2t->num_lockbytes)
879e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
880e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* All locks are read */
881e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status = NFC_STATUS_OK;
882e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
883e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
884e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
885e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
886e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
887e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
888e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
889e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_extract_default_locks_info
890e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
891e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will prepare lockbytes information for default
892e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  locks present in the tag in the absence of lock control tlv.
893e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Adding a virtual lock control tlv for these lock bytes for
894e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  easier manipulation.
895e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
896e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          None
897e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
898e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
899e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid rw_t2t_extract_default_locks_info (void)
900e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
901e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_dynamic_lock_bits;
902e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_dynamic_lock_bytes;
903e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       xx;
904e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
905e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    const       tT2T_INIT_TAG *p_ret;
906e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB;
907e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
908e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
909e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (p_t2t->num_lock_tlvs == 0)
910e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC)  )
911e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
912e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* No Lock control tlv is detected. Indicates lock bytes are present in default location */
913e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Add a virtual Lock tlv to map this default lock location */
914e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
915e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            bytes_locked_per_lock_bit = p_ret->default_lock_blpb;
916e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
917e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_dynamic_lock_bits   = ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) - (T2T_STATIC_SIZE - T2T_HEADER_SIZE)) / bytes_locked_per_lock_bit;
918e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_dynamic_lock_bytes  = num_dynamic_lock_bits / 8;
919e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0:1;
920e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
921e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset                = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
922e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit  = bytes_locked_per_lock_bit;
923e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits              = num_dynamic_lock_bits;
924e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
925e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Based on tag data size the number of locks present in the default location changes */
926e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        for (xx = 0; xx < num_dynamic_lock_bytes; xx++)
927e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
928e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->lockbyte[xx].tlv_index   = p_t2t->num_lock_tlvs;
929e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->lockbyte[xx].byte_index  = xx;
930e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->lockbyte[xx].b_lock_read = FALSE;
931e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
932e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_lockbytes = num_dynamic_lock_bytes;
933e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_lock_tlvs = 1;
934e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
935e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
936e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
937e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
938e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
939e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_read_ndef_last_block
940e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
941e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will locate and read the last ndef block.
942e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  The last ndef block refers to the tag block where last byte
943e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  of new ndef message will reside. Also this function will
944e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  locate the offset of Terminator TLV based on the size of
945e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  new NDEF Message
946e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
947e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK,if able to locate last ndef block & read started
948e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Otherwise, error status.
949e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
950e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
951e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_read_ndef_last_block (void)
952e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
953e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
954e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN) ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
955e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      num_ndef_bytes;
956e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      total_ndef_bytes;
957e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      last_ndef_byte_offset;
958e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      terminator_tlv_byte_index;
959e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status;
960e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      block;
961e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
962e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
963e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    total_ndef_bytes        = header_len + p_t2t->new_ndef_msg_len;
964e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    num_ndef_bytes          = 0;
965e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    last_ndef_byte_offset   = p_t2t->ndef_header_offset;
966e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
967e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Locate NDEF final block based on the size of new NDEF Message */
968e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (num_ndef_bytes < total_ndef_bytes)
969e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
970e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_is_lock_res_byte ((UINT16) (last_ndef_byte_offset)) == FALSE)
971e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_ndef_bytes++;
972e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
973e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        last_ndef_byte_offset++;
974e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
975e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->ndef_last_block_num = (UINT16) ((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE);
976e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block  = p_t2t->ndef_last_block_num;
977e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
978e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK;
979e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Read NDEF last block before updating */
980e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((status = rw_t2t_read (block))== NFC_STATUS_OK)
981e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
982e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len)
983e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
984e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Locate Terminator TLV Block */
985e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            total_ndef_bytes++;
986e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            terminator_tlv_byte_index = last_ndef_byte_offset;
987e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
988e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (num_ndef_bytes < total_ndef_bytes)
989e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
990e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rw_t2t_is_lock_res_byte ((UINT16) terminator_tlv_byte_index) == FALSE)
991e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        num_ndef_bytes++;
992e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
993e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                terminator_tlv_byte_index++;
994e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
995e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
996e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->terminator_byte_index = terminator_tlv_byte_index - 1;
997e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
998e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
999e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1000e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* No space for Terminator TLV */
1001e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->terminator_byte_index = 0x00;
1002e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1003e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1004e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
1005e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1006e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1007e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1008e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1009e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_read_terminator_tlv_block
1010e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1011e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will read the block where terminator tlv will
1012e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  be added later
1013e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1014e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
1015e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1016e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1017e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_read_terminator_tlv_block (void)
1018e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1019e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1020e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status;
1021e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      block;
1022e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1023e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */
1024e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block  = p_t2t->terminator_byte_index / T2T_BLOCK_SIZE;
1025e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block -= block % T2T_READ_BLOCKS;
1026e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1027e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK;
1028e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Read the block where Terminator TLV may be added later during NDEF Write operation */
1029e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    status = rw_t2t_read (block);
1030e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
1031e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1032e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1033e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1034e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1035e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_read_ndef_next_block
1036e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1037e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will read the tag block passed as argument
1038e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1039e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
1040e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1041e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1042e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block)
1043e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1044e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1045e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status;
1046e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1047e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */
1048e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block -= block % T2T_READ_BLOCKS;
1049e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1050e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK;
1051e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Read the block */
1052e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    status = rw_t2t_read (block);
1053e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1054e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
1055e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1056e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1057e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1058e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1059e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_is_read_before_write_block
1060e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1061e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will check if the block has to be read before
1062e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  writting to avoid over writting in to lock/reserved bytes
1063e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  present in the block.
1064e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  If no bytes in the block can be overwritten it moves in to
1065e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  next block and check. Finally it finds a block where part of
1066e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  ndef bytes can exist and check if the whole block can be
1067e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  updated or only part of block can be modified.
1068e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1069e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          TRUE, if the block returned should be read before writting
1070e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  FALSE, if the block need not be read as it was already
1071e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                         read or during NDEF write we may completely overwrite
1072e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                         the block and there is no reserved or locked bytes in
1073e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                         that block
1074e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1075e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1076e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read)
1077e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1078e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
1079e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       *p_cc   = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1080e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       count;
1081e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       index;
1082e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1083e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN     read_before_write = TRUE;
1084e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1085e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1086e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE)
1087e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1088e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* First NDEF block is already read */
1089e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        read_before_write = FALSE;
1090e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->ndef_read_block,p_t2t->ndef_first_block,T2T_BLOCK_SIZE);
1091e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1092e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else if (block == p_t2t->ndef_last_block_num)
1093e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1094e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Last NDEF block is already read */
1095e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        read_before_write = FALSE;
1096e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->ndef_read_block,p_t2t->ndef_last_block,T2T_BLOCK_SIZE);
1097e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1098e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE)
1099e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Terminator tlv block is already read */
1101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        read_before_write = FALSE;
1102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->ndef_read_block,p_t2t->terminator_tlv_block,T2T_BLOCK_SIZE);
1103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        count = 0;
1107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (block < tag_size)
1108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            index = 0;
1110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (index < T2T_BLOCK_SIZE)
1112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* check if it is a reserved or locked byte */
1114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
1115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
1116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    count++;
1117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
1118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                index++;
1119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (count == T2T_BLOCK_SIZE)
1121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* All the bytes in the block are free to NDEF write  */
1123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                read_before_write = FALSE;
1124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
1125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (count == 0)
1127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* The complete block is not free for NDEF write  */
1129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                index = 0;
1130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                block++;
1131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
1133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* The block has reseved byte (s) or locked byte (s) or both */
1135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                read_before_write = TRUE;
1136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
1137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Return the block to read next before NDEF write */
1141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    *p_block_to_read = block;
1142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return read_before_write;
1143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_write_ndef_first_block
1148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will write the first NDEF block with Length
1150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  field reset to zero.
1151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Also after writting NDEF this function may be called to
1152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  update new NDEF length
1153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
1155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len)
1158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       new_lengthfield_len;
1161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       write_block[4];
1162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       block;
1163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status;
1166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       length_field[3];
1167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       index;
1168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->work_offset = 0;
1170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (new_lengthfield_len == 3)
1172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* New NDEF is Long NDEF */
1174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (msg_len == 0)
1175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Clear NDEF length field */
1177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            length_field[0] = 0x00;
1178e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            length_field[1] = 0x00;
1179e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            length_field[2] = 0x00;
1180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1183e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Update NDEF length field with new NDEF Msg len */
1184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            length_field[1] = (UINT8) (msg_len >> 8);
1186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            length_field[2] = (UINT8) (msg_len);
1187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* New NDEF is Short NDEF */
1192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        length_field[0] = (UINT8) (msg_len);
1193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* updating ndef_first_block with new ndef message */
1196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memcpy (write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
1197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE;
1199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block = (UINT8) (p_t2t->ndef_header_offset / T2T_BLOCK_SIZE);
1200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (p_t2t->work_offset == 0 && block < total_blocks)
1202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* update length field */
1204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len)
1205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
1207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                write_block[index] = length_field[p_t2t->work_offset];
1209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->work_offset++;
1210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            index++;
1212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->work_offset == new_lengthfield_len)
1213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
1215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* If more space in this block then add ndef message */
1218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
1219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
1221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->work_offset++;
1224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            index++;
1226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->work_offset == 0)
1228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* If no bytes are written move to next block */
1230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            index = 0;
1231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            block++;
1232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (block == p_t2t->ndef_last_block_num)
1233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                memcpy (write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
1235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->work_offset == 0)
1239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status  = NFC_STATUS_FAILED;
1241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_update_cb (block, write_block, b_update_len);
1245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update the identified block with newly prepared data */
1246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_write (block, write_block)) == NFC_STATUS_OK)
1247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->b_read_data = FALSE;
1249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
1252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_write_ndef_next_block
1257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function can be called to write an NDEF message block
1259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
1261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len)
1264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       new_lengthfield_len;
1267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       write_block[4];
1268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      initial_offset;
1271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       length_field[3];
1272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       index;
1273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status;
1274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Write NDEF Message */
1276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    index = 0;
1279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memcpy (write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE);
1281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->work_offset >= new_lengthfield_len)
1283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Length field is updated, write ndef message field */
1285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        initial_offset = p_t2t->work_offset;
1286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (p_t2t->work_offset == initial_offset && block < total_blocks)
1287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
1289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
1291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
1292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->work_offset++;
1294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
1295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                index++;
1296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->work_offset == initial_offset)
1298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1299e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                index = 0;
1300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                block++;
1301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Complete writting Length field and then write ndef message */
1307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (new_lengthfield_len == 3)
1309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* New NDEF is Long NDEF */
1311e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (msg_len == 0)
1312e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1313e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                length_field[0] = 0x00;
1314e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                length_field[1] = 0x00;
1315e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                length_field[2] = 0x00;
1316e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1317e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
1318e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1319e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1320e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                length_field[1] = (UINT8) (msg_len >> 8);
1321e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                length_field[2] = (UINT8) (msg_len);
1322e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1323e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1324e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1325e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1326e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* New NDEF is short NDEF */
1327e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            length_field[0] = (UINT8) (msg_len);
1328e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1329e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        initial_offset = p_t2t->work_offset;
1330e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (p_t2t->work_offset == initial_offset && block < total_blocks)
1331e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1332e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Update length field */
1333e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len)
1334e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1335e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
1336e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
1337e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    write_block[index] = length_field[p_t2t->work_offset];
1338e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->work_offset++;
1339e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
1340e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                index++;
1341e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (p_t2t->work_offset == new_lengthfield_len)
1342e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
1343e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    break;
1344e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
1345e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1346e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Update ndef message field */
1347e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
1348e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1349e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
1350e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
1351e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1352e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->work_offset++;
1353e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
1354e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                index++;
1355e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1356e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->work_offset == initial_offset)
1357e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1358e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                index = 0;
1359e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                block++;
1360e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1361e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1362e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1363e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->work_offset == initial_offset)
1364e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1365e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status  = NFC_STATUS_FAILED;
1366e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1367e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1368e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1369e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_update_cb (block, write_block, b_update_len);
1370e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Write the NDEF Block */
1371e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status = rw_t2t_write (block, write_block);
1372e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1373e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1374e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
1375e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1376e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1377e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1378e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1379e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_update_cb
1380e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1381e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function can be called to write an NDEF message block
1382e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1383e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
1384e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1385e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1386e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len)
1387e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1388e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1389e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       new_lengthfield_len;
1390e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1391e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Write NDEF Message */
1392e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1393e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1394e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE)
1395e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1396e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update ndef first block if the 'block' points to ndef first block */
1397e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->ndef_first_block,p_write_block,T2T_BLOCK_SIZE);
1398e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1399e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->terminator_byte_index/T2T_BLOCK_SIZE == block)
1400e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1401e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update terminator block if the 'block' points to terminator tlv block */
1402e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN);
1403e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1404e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (b_update_len == FALSE)
1405e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1406e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (block == p_t2t->ndef_last_block_num)
1407e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1408e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK;
1409e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->work_offset      = 0;
1410e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Update ndef final block if the 'block' points to ndef final block */
1411e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE);
1412e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1413e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1414e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1415e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK;
1416e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1417e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1418e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1419e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1420e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (block == p_t2t->ndef_last_block_num)
1421e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1422e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Update the backup of Ndef final block TLV block */
1423e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE);
1424e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1425e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1426e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->work_offset >= new_lengthfield_len)
1427e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1428e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->terminator_byte_index != 0)
1429e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1430e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Add Terminator TLV as part of NDEF Write operation */
1431e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK;
1432e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1433e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
1434e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1435e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Skip adding Terminator TLV */
1436e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1437e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1438e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1439e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1440e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1441e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Part of NDEF Message Len should be added in the next block */
1442e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK;
1443e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1444e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1445e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1446e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1447e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1448e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1449e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_get_ndef_flags
1450e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1451e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Prepare NDEF Flags
1452e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1453e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NDEF Flag value
1454e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1455e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1456e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic UINT8 rw_t2t_get_ndef_flags (void)
1457e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1458e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       flags   = 0;
1459e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
1460e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    const       tT2T_INIT_TAG *p_ret;
1461e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1462e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    flags |= RW_NDEF_FL_SUPPORTED;
1463e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1464e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) || (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0))
1465e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        flags |= RW_NDEF_FL_FORMATABLE;
1466e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1467e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
1468e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        flags |=RW_NDEF_FL_READ_ONLY;
1469e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1470e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
1471e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_ret->b_otp)  )
1472e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1473e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Set otp flag */
1474e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        flags |= RW_NDEF_FL_OTP;
1475e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1476e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Set Read only flag if otp tag already has NDEF Message */
1477e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->ndef_msg_len)
1478e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            flags |= RW_NDEF_FL_READ_ONLY;
1479e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1480e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return flags;
1481e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1482e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1483e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1484e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1485e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_get_ndef_max_size
1486e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1487e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Calculate maximum size of NDEF message that can be written
1488e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  on to the tag
1489e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1490e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          Maximum size of NDEF Message
1491e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1492e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1493e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic UINT16 rw_t2t_get_ndef_max_size (void)
1494e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1495e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      offset;
1496e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       xx;
1497e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t   = &rw_cb.tcb.t2t;
1498e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN) + p_t2t->num_lockbytes;
1499e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1500e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
1501e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        tag_size += p_t2t->mem_tlv[xx].num_bytes;
1502e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1503e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    offset                  = p_t2t->ndef_msg_offset;
1504e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->max_ndef_msg_len = 0;
1505e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1506e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (tag_size < T2T_STATIC_SIZE)
1507e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ||(tag_size > (T2T_SECTOR_SIZE * T2T_MAX_SECTOR))
1508e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ||((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) && (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0))  )
1509e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1510e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Tag not formated, assume static tag */
1511e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE - T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN;
1512e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return p_t2t->max_ndef_msg_len;
1513e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1514e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1515e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Starting from NDEF Message offset find the first locked data byte */
1516e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (offset < tag_size)
1517e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1518e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_is_lock_res_byte ((UINT16) offset) == FALSE)
1519e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1520e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_is_read_only_byte ((UINT16) offset) == TRUE)
1521e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
1522e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->max_ndef_msg_len++;
1523e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1524e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        offset++;
1525e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1526e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* NDEF Length field length changes based on NDEF size */
1527e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0)
1528e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) == T2T_SHORT_NDEF_LEN_FIELD_LEN)  )
1529e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1530e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->max_ndef_msg_len -=  (p_t2t->max_ndef_msg_len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) ? 1: (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN);
1531e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1532e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return p_t2t->max_ndef_msg_len;
1533e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1534e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1535e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1536e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1537e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_add_terminator_tlv
1538e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1539e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will add terminator TLV after NDEF Message
1540e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1541e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
1542e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1543e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1544e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_add_terminator_tlv (void)
1545e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1546e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1547e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status;
1548e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      block;
1549e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1550e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Add Terminator TLV after NDEF Message */
1551e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->terminator_tlv_block[p_t2t->terminator_byte_index%T2T_BLOCK_LEN] = TAG_TERMINATOR_TLV;
1552e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1553e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1554e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block = p_t2t->terminator_byte_index/T2T_BLOCK_LEN;
1555e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    status = rw_t2t_write (block, p_t2t->terminator_tlv_block);
1556e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1557e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
1558e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1559e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1560e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1561e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1562e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_ndef_read_rsp
1563e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1564e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function handles reading an NDEF message.
1565e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1566e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
1567e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1568e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1569e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data)
1570e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1571e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB      *p_t2t = &rw_cb.tcb.t2t;
1572e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_READ_DATA    evt_data;
1573e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16          len;
1574e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16          offset;
1575e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN         failed = FALSE;
1576e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN         done   = FALSE;
1577e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1578e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* On the first read, adjust for any partial block offset */
1579e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    offset = 0;
1580e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    len    = T2T_READ_DATA_LEN;
1581e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1582e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->work_offset == 0)
1583e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1584e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* The Ndef Message offset may be present in the read 16 bytes */
1585e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
1586e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1587e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1588e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Skip all reserved and lock bytes */
1589e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (  (offset < len)
1590e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           &&(p_t2t->work_offset<p_t2t->ndef_msg_len)  )
1591e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1592e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1593e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_is_lock_res_byte ((UINT16) (offset + p_t2t->block_read * T2T_BLOCK_LEN)) == FALSE)
1594e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1595e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Collect the NDEF Message */
1596e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset];
1597e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->work_offset++;
1598e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1599e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        offset++;
1600e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1601e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1602e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->work_offset >= p_t2t->ndef_msg_len)
1603e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1604e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        done = TRUE;
1605e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->ndef_status = T2T_NDEF_READ;
1606e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1607e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
1608e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1609e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Read next 4 blocks */
1610e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_read ((UINT16) (p_t2t->block_read + T2T_READ_BLOCKS)) != NFC_STATUS_OK)
1611e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            failed = TRUE;
1612e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1613e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1614e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (failed || done)
1615e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1616e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1617e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt_data.p_data = NULL;
1618e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_op_complete ();
1619e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        (*rw_cb.p_cback) (RW_T2T_NDEF_READ_EVT, (tRW_DATA *) &evt_data);
1620e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1621e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1622e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1623e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1624e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1625e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_ndef_write_rsp
1626e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1627e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Handle response received to reading (or part of) NDEF message.
1628e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1629e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
1630e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1631e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1632e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data)
1633e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1634e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB      *p_t2t = &rw_cb.tcb.t2t;
1635e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_READ_DATA   evt_data;
1636e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN         failed = FALSE;
1637e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN         done   = FALSE;
1638e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16          block;
1639e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8           offset;
1640e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1641e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    switch (p_t2t->substate)
1642e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1643e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
1644e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1645e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Backup the read NDEF first block */
1646e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           memcpy (p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN);
1647e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Read ndef final block */
1648e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_read_ndef_last_block () !=  NFC_STATUS_OK)
1649e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            failed = TRUE;
1650e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1651e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1652e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
1653e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1654e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        offset = (UINT8) (p_t2t->ndef_last_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE;
1655e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Backup the read NDEF final block */
1656e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->ndef_last_block, &p_data[offset], T2T_BLOCK_LEN);
1657e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) == p_t2t->ndef_last_block_num)
1658e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1659e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* If Terminator TLV will reside on the NDEF Final block */
1660e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            memcpy (p_t2t->terminator_tlv_block, p_t2t->ndef_last_block, T2T_BLOCK_LEN);
1661e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!=  NFC_STATUS_OK)
1662e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
1663e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1664e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else if (p_t2t->terminator_byte_index != 0)
1665e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1666e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* If there is space for Terminator TLV and if it will reside outside NDEF Final block */
1667e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_read_terminator_tlv_block ()!=  NFC_STATUS_OK)
1668e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
1669e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1670e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1671e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1672e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!=  NFC_STATUS_OK)
1673e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
1674e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1675e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1676e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1677e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
1678e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1679e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        offset = (UINT8) (((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) - p_t2t->block_read) * T2T_BLOCK_SIZE);
1680e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Backup the read Terminator TLV block */
1681e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->terminator_tlv_block, &p_data[offset], T2T_BLOCK_LEN);
1682e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1683e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Write the first block for new NDEF Message */
1684e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!=  NFC_STATUS_OK)
1685e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           failed = TRUE;
1686e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1687e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1688e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
1689e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1690e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        offset = (UINT8) (p_t2t->ndef_read_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE;
1691e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Backup read block */
1692e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN);
1693e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1694e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update the block with new NDEF Message */
1695e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_write_ndef_next_block (p_t2t->ndef_read_block_num, 0x0000, FALSE) !=  NFC_STATUS_OK)
1696e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            failed = TRUE;
1697e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1698e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1699e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
1700e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
1701e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->block_written + 1), &block) == TRUE)
1702e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1703e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->ndef_read_block_num = block;
1704e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* If only part of the block is going to be updated read the block to retain previous data for
1705e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project               unchanged part of the block */
1706e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_read_ndef_next_block (block) !=  NFC_STATUS_OK)
1707e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
1708e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1709e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1710e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1711e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK)
1712e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1713e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Directly write the block with new NDEF contents as whole block is going to be updated */
1714e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rw_t2t_write_ndef_next_block (block, p_t2t->new_ndef_msg_len, TRUE)!=  NFC_STATUS_OK)
1715e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                   failed = TRUE;
1716e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1717e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
1718e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1719e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Directly write the block with new NDEF contents as whole block is going to be updated */
1720e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (rw_t2t_write_ndef_next_block (block, 0x0000, FALSE)!=  NFC_STATUS_OK)
1721e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                   failed = TRUE;
1722e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1723e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1724e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1725e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1726e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
1727e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Write the next block for new NDEF Message */
1728e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE;
1729e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->ndef_write_block), &block) == TRUE)
1730e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1731e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* If only part of the block is going to be updated read the block to retain previous data for
1732e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project               part of the block thats not going to be changed */
1733e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK;
1734e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_read (block) !=  NFC_STATUS_OK)
1735e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                failed = TRUE;
1736e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1737e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1738e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1739e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1740e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Update NDEF Message Length in the Tag */
1741e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (rw_t2t_write_ndef_first_block (p_t2t->new_ndef_msg_len, TRUE)!=  NFC_STATUS_OK)
1742e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project               failed = TRUE;
1743e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1744e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1745e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1746e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
1747e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Backup read block */
1748e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN);
1749e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1750e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update the block with new NDEF Message */
1751e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_write_ndef_next_block (p_t2t->block_read, p_t2t->new_ndef_msg_len, TRUE) ==  NFC_STATUS_OK)
1752e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->ndef_write_block = p_t2t->block_read + 1;
1753e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1754e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            failed = TRUE;
1755e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1756e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1757e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1758e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
1759e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (rw_t2t_add_terminator_tlv ()!=  NFC_STATUS_OK)
1760e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           failed = TRUE;
1761e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1762e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1763e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
1764e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        done = TRUE;
1765e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1766e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1767e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    default:
1768e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1769e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1770e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1771e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (failed || done)
1772e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1773e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt_data.p_data = NULL;
1774e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* NDEF WRITE Operation is done, inform up the stack */
1775e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1776e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (done)
1777e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1778e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (  (p_t2t->ndef_msg_len >= 0x00FF)
1779e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                &&(p_t2t->new_ndef_msg_len < 0x00FF)  )
1780e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1781e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->ndef_msg_offset -= 2;
1782e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1783e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else if (  (p_t2t->new_ndef_msg_len >= 0x00FF)
1784e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                     &&(p_t2t->ndef_msg_len < 0x00FF)  )
1785e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1786e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->ndef_msg_offset += 2;
1787e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1788e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len;
1789e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1790e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_op_complete ();
1791e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        (*rw_cb.p_cback) (RW_T2T_NDEF_WRITE_EVT, (tRW_DATA *) &evt_data);
1792e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1793e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1794e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1795e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1796e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1797e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_get_tag_size
1798e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1799e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function calculates tag data area size from data read
1800e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  from block with version number
1801e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1802e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          TMS of the tag
1803e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1804e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1805e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic UINT8 rw_t2t_get_tag_size (UINT8 *p_data)
1806e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1807e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16  LchunkSize = 0;
1808e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16  Num_LChuncks = 0;
1809e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16  tms = 0;
1810e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1811e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    LchunkSize   = (UINT16) p_data[2] << 8 | p_data[3];
1812e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    Num_LChuncks = (UINT16) p_data[4] << 8 | p_data[5];
1813e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1814e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tms = (UINT16) (LchunkSize * Num_LChuncks);
1815e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1816e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE);
1817e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1818e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tms /= 0x08;
1819e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1820e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (UINT8) tms;
1821e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1822e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1823e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1824e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1825e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_config_tag_readonly
1826e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1827e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function handles configure type 2 tag as read only
1828e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1829e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
1830e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1831e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1832e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_config_tag_readonly (UINT8 *p_data)
1833e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1834e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1835e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status  = NFC_STATUS_FAILED;
1836e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN     b_notify = FALSE;
1837e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       write_block[T2T_BLOCK_SIZE];
1838e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_DATA    evt;
1839e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN     b_pending = FALSE;
1840e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       read_lock = 0;
1841e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_locks = 0;
1842e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      offset;
1843e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1844e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    switch (p_t2t->substate)
1845e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1846e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_CC:
1847e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1848e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* First soft lock the tag */
1849e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_soft_lock_tag ();
1850e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1851e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1852e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1853e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_SET_CC_RO:
1854e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1855e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Successfully soft locked! Update Tag header for future reference */
1856e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO;
1857e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (!p_t2t->b_hard_lock)
1858e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1859e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Tag configuration complete */
1860e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            status   = NFC_STATUS_OK;
1861e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            b_notify = TRUE;
1862e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
1863e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1864e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1865e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Coverity: [FALSE-POSITIVE error] intended fall through */
1866e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Missing break statement between cases in switch statement */
1867e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* fall through */
1868e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
1869e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1870e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_locks = 0;
1871e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1872e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (num_locks < p_t2t->num_lockbytes)
1873e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1874e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_UPDATE_INITIATED)
1875e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1876e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Update control block as one or more dynamic lock byte (s) are set */
1877e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED;
1878e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1879e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (!b_pending && p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED)
1880e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
1881e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* One or more dynamic lock bits are not set */
1882e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                b_pending = TRUE;
1883e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                read_lock = num_locks;
1884e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
1885e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_locks++;
1886e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1887e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1888e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (b_pending)
1889e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1890e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Read the block where dynamic lock bits are present to avoid writing to NDEF bytes in the same block */
1891e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset = p_t2t->lock_tlv[p_t2t->lockbyte[read_lock].tlv_index].offset + p_t2t->lockbyte[read_lock].byte_index;
1892e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate    = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK;
1893e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            status = rw_t2t_read ((UINT16) (offset / T2T_BLOCK_LEN));
1894e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1895e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1896e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1897e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Now set Static lock bits as no more dynamic lock bits to set */
1898e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1899e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Copy the internal bytes */
1900e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            memcpy (write_block, &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN], T2T_INTERNAL_BYTES_LEN);
1901e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Set all Static lock bits */
1902e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            write_block [T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF;
1903e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            write_block [T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF;
1904e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
1905e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            status = rw_t2t_write ((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block);
1906e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1907e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1908e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1909e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK:
1910e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Now set the dynamic lock bits present in the block read now */
1911e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status = rw_t2t_set_dynamic_lock_bits (p_data);
1912e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1913e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1914e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
1915e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Tag configuration complete */
1916e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status   = NFC_STATUS_OK;
1917e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        b_notify = TRUE;
1918e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1919e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1920e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1921e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1922e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (status != NFC_STATUS_OK || b_notify)
1923e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1924e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Notify upper layer the result of Configuring Tag as Read only */
1925e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt.status      = status;
1926e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_op_complete ();
1927e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        (*rw_cb.p_cback) (RW_T2T_SET_TAG_RO_EVT, (tRW_DATA *) &evt);
1928e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
1929e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
1930e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1931e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
1932e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1933e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_handle_format_tag_rsp
1934e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1935e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function handles formating a type 2 tag
1936e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1937e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          none
1938e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
1939e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
1940e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_handle_format_tag_rsp (UINT8 *p_data)
1941e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
1942e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_DATA    evt;
1943e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       *p;
1944e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
1945e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status  = NFC_STATUS_FAILED;
1946e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      version_no;
1947e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    const       tT2T_INIT_TAG *p_ret;
1948e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       tms;
1949e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       next_block = T2T_FIRST_DATA_BLOCK + 1;
1950e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      addr, locked_area;
1951e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN     b_notify = FALSE;
1952e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1953e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1954e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p = p_t2t->ndef_final_block;
1955e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8_TO_BE_STREAM (p, p_t2t->tlv_value[2]);
1956e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1957e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    switch (p_t2t->substate)
1958e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
1959e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_CC:
1960e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Start format operation */
1961e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status = rw_t2t_format_tag ();
1962e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1963e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1964e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO:
1965e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1966e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memcpy (p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
1967e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->b_read_data = TRUE;
1968e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        version_no = (UINT16) p_data[0] << 8 | p_data[1];
1969e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) != NULL)
1970e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1971e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Valid Version Number */
1972e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_ret->b_calc_cc)
1973e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Calculate tag size from Version Information */
1974e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                tms = rw_t2t_get_tag_size (p_data);
1975e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1976e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
1977e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Tag size from Look up table */
1978e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                tms = p_ret->tms;
1979e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1980e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Set CC with the Tag size from look up table or from calculated value */
1981e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            status = rw_t2t_set_cc (tms);
1982e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1983e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
1984e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1985e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_SET_CC:
1986e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
1987e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        version_no = (UINT16) p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1];
1988e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (  (version_no == 0)
1989e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ||((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) == NULL)
1990e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ||(!p_ret->b_multi_version)
1991e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ||(!p_ret->b_calc_cc)  )
1992e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
1993e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Currently Formating a non blank tag or a blank tag with manufacturer
1994e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project             * has only one variant of tag. Set Null NDEF TLV and complete Format Operation */
1995e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            next_block = T2T_FIRST_DATA_BLOCK;
1996e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p = p_t2t->ndef_final_block;
1997e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
1998e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
1999e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2000e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            addr        = (UINT16) (((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[4] << 8 | p_t2t->tag_data[5]) + T2T_STATIC_SIZE);
2001e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            locked_area = ((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[6]);
2002e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2003e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if ((status = rw_t2t_set_lock_tlv (addr, p_t2t->tag_data[7], locked_area)) == NFC_STATUS_REJECTED)
2004e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2005e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format Operation */
2006e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                next_block = T2T_FIRST_DATA_BLOCK;
2007e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p = p_t2t->ndef_final_block;
2008e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2009e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
2010e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                break;
2011e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2012e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2013e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* falls through */
2014e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV:
2015e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2016e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Prepare NULL NDEF TLV, TERMINATOR_TLV */
2017e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV);
2018e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_BE_STREAM (p, 0);
2019e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2020e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (  ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
2021e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            &&(!p_ret->b_otp)  )
2022e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2023e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT8_TO_BE_STREAM (p, TAG_TERMINATOR_TLV);
2024e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2025e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
2026e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            UINT8_TO_BE_STREAM (p, 0);
2027e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2028e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF;
2029e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* send WRITE-E8 command */
2030e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_write (next_block, p_t2t->ndef_final_block)) == NFC_STATUS_OK)
2031e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->b_read_data = FALSE;
2032e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
2033e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2034e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF:
2035e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Tag Formated successfully */
2036e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status   = NFC_STATUS_OK;
2037e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        b_notify = TRUE;
2038e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
2039e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2040e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    default:
2041e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        break;
2042e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2043e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2044e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2045e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (status != NFC_STATUS_OK || b_notify)
2046e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2047e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Notify upper layer the result of Format op */
2048e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        evt.status      = status;
2049e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_op_complete ();
2050e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        (*rw_cb.p_cback) (RW_T2T_FORMAT_CPLT_EVT, (tRW_DATA *) &evt);
2051e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2052e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2053e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2054e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2055e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2056e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2057e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_update_attributes
2058e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2059e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will update attribute for the current segment
2060e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  based on lock and reserved bytes
2061e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2062e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          None
2063e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2064e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2065e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_update_attributes (void)
2066e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2067e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       count = 0;
2068e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2069e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      lower_offset;
2070e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      upper_offset;
2071e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      offset;
2072e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_bytes;
2073e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2074e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Prepare attr for the current segment */
2075e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memset (p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8));
2076e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2077e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* calculate offset where the current segment starts in the tag */
2078e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    lower_offset   = p_t2t->segment * RW_T2T_SEGMENT_BYTES;
2079e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* calculate offset where the current segment ends in the tag */
2080e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    upper_offset   = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES;
2081e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2082e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2083e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* check offset of lock bytes in the tag and update p_t2t->attr
2084e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     * for every lock byte that is present in the current segment */
2085e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    count = 0;
2086e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (count < p_t2t->num_lockbytes)
2087e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2088e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset + p_t2t->lockbyte[count].byte_index;
2089e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (offset >= lower_offset && offset < upper_offset)
2090e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2091e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Calculate offset in the current segment as p_t2t->attr is prepared for one segment only */
2092e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset %= RW_T2T_SEGMENT_BYTES;
2093e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not
2094e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project             * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
2095e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project             * Set the corresponding bit in attr to indicate - reserved byte */
2096e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->attr[offset / TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
2097e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2098e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        count++;
2099e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Search reserved bytes identified by all memory tlvs present in the tag */
2103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    count = 0;
2104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (count < p_t2t->num_mem_tlvs)
2105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* check the offset of reserved bytes in the tag and update  p_t2t->attr
2107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project         * for every  reserved byte that is present in the current segment */
2108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_bytes = 0;
2109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (num_bytes < p_t2t->mem_tlv[count].num_bytes)
2110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset = p_t2t->mem_tlv[count].offset + num_bytes;
2112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (offset >= lower_offset && offset < upper_offset)
2113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Let offset represents offset in the current segment as p_t2t->attr is prepared for one segment only */
2115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                offset %= RW_T2T_SEGMENT_BYTES;
2116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not
2117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                 * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
2118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                 * Set the corresponding bit in attr to indicate - reserved byte */
2119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->attr[offset /TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
2120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_bytes++;
2122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        count++;
2124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_get_lock_bits_for_segment
2130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function returns the offset of lock bits associated for
2132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  the specified segment
2133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      segment: The segment number to which lock bits are associated
2135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  p_start_byte: The offset of lock byte that contains the first
2136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                                lock bit for the segment
2137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  p_start_bit:  The offset of the lock bit in the lock byte
2138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  p_end_byte:   The offset of the last bit associcated to the
2140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                                segment
2141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          Total number of lock bits assigned to the specified segment
2143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic UINT8 rw_t2t_get_lock_bits_for_segment (UINT8 segment, UINT8 *p_start_byte, UINT8 *p_start_bit, UINT8 *p_end_byte)
2146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       total_bits = 0;
2148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      byte_count = 0;
2149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      lower_offset, upper_offset;
2150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_dynamic_locks = 0;
2151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       bit_count  = 0;
2152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       bytes_locked_per_bit;
2153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_bits;
2154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN     b_all_bits_are_locks = TRUE;
2156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      tag_size;
2157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       xx;
2158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tag_size      = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes;
2160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
2162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        tag_size += p_t2t->mem_tlv[xx].num_bytes;
2163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    lower_offset  = segment * RW_T2T_SEGMENT_BYTES;
2165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (segment == 0)
2166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        lower_offset  += T2T_STATIC_SIZE;
2168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    upper_offset  = (segment + 1) * RW_T2T_SEGMENT_BYTES;
2170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    byte_count = T2T_STATIC_SIZE;
2172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (tag_size < upper_offset)
2173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        upper_offset = tag_size;
2175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    *p_start_byte = num_dynamic_locks;
2178e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    *p_start_bit  = 0;
2179e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (  (byte_count <= lower_offset)
2181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           &&(num_dynamic_locks < p_t2t->num_lockbytes)  )
2182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2183e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
2184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Number of bits in the current lock byte */
2185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
2186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset)
2189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Skip this lock byte as it covers different segment */
2191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            byte_count += bytes_locked_per_bit * num_bits;
2192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_dynamic_locks++;
2193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
2195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            bit_count = 0;
2197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (bit_count < num_bits)
2198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                byte_count += bytes_locked_per_bit;
2200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (byte_count > lower_offset)
2201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
2202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* First lock bit that is used to lock this segment */
2203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    *p_start_byte = num_dynamic_locks;
2204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    *p_end_byte   = num_dynamic_locks;
2205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    *p_start_bit  = bit_count;
2206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    bit_count++;
2207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    total_bits    = 1;
2208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    break;
2209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
2210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                bit_count++;
2211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (num_dynamic_locks == p_t2t->num_lockbytes)
2215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return 0;
2217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (  (byte_count < upper_offset)
2219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project           &&(num_dynamic_locks < p_t2t->num_lockbytes)  )
2220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
2222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Number of bits in the current lock byte */
2223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
2224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset)
2227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Collect all lock bits that covers the current segment */
2229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            byte_count += bytes_locked_per_bit * (num_bits - bit_count);
2230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            total_bits += num_bits - bit_count;
2231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            bit_count   = 0;
2232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            *p_end_byte = num_dynamic_locks;
2233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_dynamic_locks++;
2234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
2236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* The last lock byte that covers the current segment */
2238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            bit_count = 0;
2239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (bit_count < num_bits)
2240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* The last lock bit that is used to lock this segment */
2242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                byte_count += bytes_locked_per_bit;
2243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (byte_count >= upper_offset)
2244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
2245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    *p_end_byte = num_dynamic_locks;
2246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    total_bits  += (bit_count + 1);
2247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    break;
2248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
2249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                bit_count++;
2250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return total_bits;
2254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_update_lock_attributes
2259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will check if the tag index passed as
2261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  argument is a locked byte and return TRUE or FALSE
2262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      index, the index of the byte in the tag
2264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          TRUE, if the specified index in the tag is a locked or
2267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                        reserved or otp byte
2268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  FALSE, otherwise
2269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void rw_t2t_update_lock_attributes (void)
2272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t                      = &rw_cb.tcb.t2t;
2274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       xx                          = 0;
2275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_static_lock_bytes       = 0;
2276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_dyn_lock_bytes          = 0;
2277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       bits_covered                = 0;
2278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       bytes_covered               = 0;
2279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       block_count                 = 0;
2280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN     b_all_bits_are_locks        = TRUE;
2281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       bytes_locked_per_lock_bit;
2282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       start_lock_byte;
2283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       start_lock_bit;
2284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       end_lock_byte;
2285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_lock_bits;
2286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       total_bits;
2287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Prepare lock_attr for the current segment */
2290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memset (p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8));
2291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block_count                 = 0;
2293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->segment == 0)
2294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update lock_attributes based on static lock bytes */
2296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        xx                      = 0;
2297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_static_lock_bytes   = 0;
2298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        block_count             = 0;
22995c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        num_lock_bits           = TAG_BITS_PER_BYTE - 1; /* the inner while loop increases xx by 2. need (-1) to avoid coverity overrun error */
2300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (num_static_lock_bytes < T2T_NUM_STATIC_LOCK_BYTES)
2302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Update lock attribute based on 2 static locks */
2304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (xx < num_lock_bits)
2305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->lock_attr[block_count] = 0x00;
2307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] & rw_t2t_mask_bits[xx++])
2309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
2310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* If the bit is set then 1 block is locked */
2311e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->lock_attr[block_count] = 0x0F;
2312e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
2313e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2314e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] & rw_t2t_mask_bits[xx++])
2315e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
2316e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* If the bit is set then 1 block is locked */
2317e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->lock_attr[block_count] |= 0xF0;
2318e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
2319e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                block_count++;
2320e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2321e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_static_lock_bytes++;
2322e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            xx = 0;
2323e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2324e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* UID is always locked, irrespective of the lock value */
2325e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->lock_attr[0x00] = 0xFF;
2326e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2327e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2328e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Get lock bits applicable for the current segment */
2329e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((total_bits = rw_t2t_get_lock_bits_for_segment (p_t2t->segment,&start_lock_byte, &start_lock_bit, &end_lock_byte)) != 0)
2330e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2331e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* update lock_attributes based on current segment using dynamic lock bytes */
2332e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        xx                            = start_lock_bit;
2333e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_dyn_lock_bytes            = start_lock_byte;
2334e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        bits_covered                  = 0;
2335e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        bytes_covered                 = 0;
2336e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_lock_bits                 = TAG_BITS_PER_BYTE;
2337e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->lock_attr[block_count] = 0;
2338e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2339e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (num_dyn_lock_bytes <= end_lock_byte)
2340e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2341e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            bytes_locked_per_lock_bit  = p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].bytes_locked_per_bit;
2342e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Find number of bits in the byte are lock bits */
2343e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            b_all_bits_are_locks = ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits);
2344e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_lock_bits        =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2345e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2346e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (xx < num_lock_bits)
2347e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2348e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                bytes_covered = 0;
2349e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                while (bytes_covered < bytes_locked_per_lock_bit)
2350e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
2351e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte & rw_t2t_mask_bits[xx])
2352e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
2353e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* If the bit is set then it is locked */
2354e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
2355e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
2356e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    bytes_covered++;
2357e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    bits_covered++;
2358e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    if (bits_covered == TAG_BITS_PER_BYTE)
2359e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    {
2360e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Move to next 8 bytes */
2361e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        bits_covered = 0;
2362e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        block_count++;
2363e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        /* Assume unlocked before updating using locks */
2364e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                        if (block_count < RW_T2T_SEGMENT_SIZE)
2365e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                            p_t2t->lock_attr[block_count] = 0;
2366e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    }
2367e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
2368e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                xx++;
2369e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2370e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_dyn_lock_bytes++;
2371e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            xx = 0;
2372e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2373e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2374e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2375e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2376e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2377e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2378e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_is_lock_res_byte
2379e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2380e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will check if the tag index passed as
2381e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  argument is a lock or reserved or otp byte and return
2382e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  TRUE or FALSE
2383e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2384e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      index, the index of the byte in the tag
2385e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2386e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2387e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          TRUE, if the specified index in the tag is a locked or
2388e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                        reserved or otp byte
2389e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  FALSE, otherwise
2390e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2391e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2392e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index)
2393e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2394e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2395e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2396e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES);
2397e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2398e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->attr_seg != p_t2t->segment)
2399e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2400e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update attributes for the current segment */
2401e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_update_attributes ();
2402e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->attr_seg = p_t2t->segment;
2403e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2404e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2405e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    index = index % RW_T2T_SEGMENT_BYTES;
2406e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a lock/reserved byte or not
2407e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
2408e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
2409e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     * p_t2t->attr[block/2] is set or not. If the bit is set then it is a lock/reserved byte, otherwise not */
2410e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2411e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return ((p_t2t->attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
2412e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2413e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2414e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2415e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2416e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_is_read_only_byte
2417e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2418e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will check if the tag index passed as
2419e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  argument is a locked and return
2420e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  TRUE or FALSE
2421e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2422e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      index, the index of the byte in the tag
2423e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2424e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2425e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          TRUE, if the specified index in the tag is a locked or
2426e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                        reserved or otp byte
2427e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  FALSE, otherwise
2428e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2429e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2430e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic BOOLEAN rw_t2t_is_read_only_byte (UINT16 index)
2431e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2432e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2433e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2434e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES);
2435e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2436e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->lock_attr_seg != p_t2t->segment)
2437e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2438e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Update lock attributes for the current segment */
2439e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_update_lock_attributes ();
2440e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->lock_attr_seg = p_t2t->segment;
2441e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2442e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2443e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    index = index % RW_T2T_SEGMENT_BYTES;
2444e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Every bit in p_t2t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte
2445e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     * So, each array element in p_t2t->lock_attr covers two blocks of the tag as T2 block size is 4 and array element size is 8
2446e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     * Find the block and offset for the index (passed as argument) and Check if the offset bit in
2447e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project     * p_t2t->lock_attr[block/2] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */
2448e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2449e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return ((p_t2t->lock_attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
2450e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2451e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2452e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2453e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2454e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_set_dynamic_lock_bits
2455e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2456e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will set dynamic lock bits as part of
2457e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  configuring tag as read only
2458e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2459e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns
2460e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_OK, Command sent to set dynamic lock bits
2461e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_FAILED: otherwise
2462e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2463e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2464e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data)
2465e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2466e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2467e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       write_block[T2T_BLOCK_SIZE];
2468e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      offset;
2469e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      next_offset;
2470e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_bits;
2471e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       next_num_bits;
2472e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status      = NFC_STATUS_FAILED;
2473e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_locks;
2474e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       lock_count;
2475e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN     b_all_bits_are_locks = TRUE;
2476e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2477e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    num_locks = 0;
2478e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2479e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memcpy (write_block, p_data, T2T_BLOCK_SIZE);
2480e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    while (num_locks < p_t2t->num_lockbytes)
2481e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2482e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED)
2483e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2484e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
2485e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2486e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Check if all bits are lock bits in the byte */
2487e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            b_all_bits_are_locks = ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits);
2488e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2489e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2490e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            write_block[(UINT8) (offset%T2T_BLOCK_SIZE)] |=  tags_pow (2,num_bits) - 1;
2491e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            lock_count = num_locks + 1;
2492e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2493e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* Set all the lock bits in the block using a sing block write command */
2494e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            while (lock_count < p_t2t->num_lockbytes)
2495e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2496e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                next_offset          = p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset + p_t2t->lockbyte[lock_count].byte_index;
2497e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2498e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                /* Check if all bits are lock bits in the byte */
2499e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                b_all_bits_are_locks = ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits);
2500e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                next_num_bits        = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2501e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2502e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE)
2503e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
2504e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    write_block[(UINT8) (next_offset % T2T_BLOCK_SIZE)] |=  tags_pow (2, next_num_bits) - 1;
2505e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
2506e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                else
2507e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    break;
2508e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                lock_count ++;
2509e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2510e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2511e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
2512e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            /* send WRITE command to set dynamic lock bits */
2513c11a054fc2855196292b062a843321121b591cc0Evan Chu            if ((status = rw_t2t_write ((UINT16) (offset / T2T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK)
2514e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            {
2515e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                while (lock_count >  num_locks)
2516e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                {
2517e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    /* Set update initiated flag to indicate a write command is sent to set dynamic lock bits of the block */
2518e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    p_t2t->lockbyte[lock_count - 1].lock_status = RW_T2T_LOCK_UPDATE_INITIATED;
2519e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                    lock_count --;
2520e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                }
2521e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            }
2522e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            else
2523e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                status = NFC_STATUS_FAILED;
2524e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2525e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
2526e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2527e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2528e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_locks++;
2529e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2530e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2531e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
2532e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2533e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2534e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2535e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2536e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_set_lock_tlv
2537e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2538e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will set lock control tlv on the blank
2539e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  activated type 2 tag based on values read from version block
2540e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2541e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      TAG data memory size
2542e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2543e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns
2544e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_OK, Command sent to set Lock TLV
2545e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_FAILED: otherwise
2546e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2547e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2548e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size)
2549e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2550e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status  = NFC_STATUS_FAILED;
2551e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    INT8        PageAddr = 0;
2552e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    INT8        BytePerPage = 0;
2553e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    INT8        ByteOffset = 0;
2554e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       a;
2555e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       data_block[T2T_BLOCK_SIZE];
2556e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
2557e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       *p;
2558e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       xx;
2559e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2560e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    for (xx = 15; xx >0; xx--)
2561e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2562e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        a  = (UINT8) (addr / xx);
2563e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        a += (addr % xx) ? 1:0;
2564e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2565e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        BytePerPage = (INT8) tags_log2 (a);
2566e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        ByteOffset  = (INT8) (addr - xx * tags_pow (2, BytePerPage));
2567e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2568e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (ByteOffset < 16)
2569e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2570e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            PageAddr = xx;
2571e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            break;
2572e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2573e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2574e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2575e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16))
2576e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2577e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        memset (data_block, 0, T2T_BLOCK_SIZE);
2578e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p = data_block;
2579e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_BE_STREAM (p, T2T_TLV_TYPE_LOCK_CTRL);
2580e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_BE_STREAM (p, T2T_TLEN_LOCK_CTRL_TLV);
2581e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_BE_STREAM (p, (PageAddr << 4 | ByteOffset));
2582e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        UINT8_TO_BE_STREAM (p, num_dyn_lock_bits);
2583e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2584e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset;
2585e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->tlv_value[1] = num_dyn_lock_bits;
2586e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->tlv_value[2] = (UINT8) (BytePerPage << 4 | tags_log2 (locked_area_size));
2587e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2588e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV;
2589e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2590e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* send WRITE-E8 command */
2591e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_write (T2T_FIRST_DATA_BLOCK, data_block)) == NFC_STATUS_OK)
2592e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2593e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->b_read_data = FALSE;
2594e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2595e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
2596e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2597e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2598e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2599e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status = NFC_STATUS_REJECTED;
2600e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2601e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
2602e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2603e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2604e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2605e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2606e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_set_cc
2607e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2608e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will set Capability Container on the activated
2609e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  type 2 tag with default values of CC0, CC1, CC4 and specified
2610e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  CC3 value
2611e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2612e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      CC3 value of the tag
2613e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2614e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns
2615e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_OK, Command sent to set CC
2616e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_FAILED: otherwise
2617e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2618e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2619e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_set_cc (UINT8 tms)
2620e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2621e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8               cc_block[T2T_BLOCK_SIZE];
2622e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB          *p_t2t  = &rw_cb.tcb.t2t;
2623e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS         status  = NFC_STATUS_FAILED;
2624e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8               *p;
2625e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2626e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memset (cc_block, 0, T2T_BLOCK_SIZE);
2627e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memset (p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE);
2628e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p = cc_block;
2629e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2630e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Prepare Capability Container */
2631e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8_TO_BE_STREAM (p, T2T_CC0_NMN);
2632e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8_TO_BE_STREAM (p, T2T_CC1_VNO);
2633e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8_TO_BE_STREAM (p, tms);
2634e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8_TO_BE_STREAM (p, T2T_CC3_RWA_RW);
2635e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2636e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC;
2637e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2638e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* send WRITE-E8 command */
2639e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((status = rw_t2t_write (T2T_CC_BLOCK, cc_block)) == NFC_STATUS_OK)
2640e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2641e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
2642e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->b_read_hdr = FALSE;
2643e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2644e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2645e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2646e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2647e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
2648e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2649e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2650e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2651e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2652e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_format_tag
2653e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2654e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will format tag based on Manufacturer ID
2655e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2656e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns
2657e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_OK, Command sent to format Tag
2658e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_FAILED: otherwise
2659e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2660e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2661e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_format_tag (void)
2662e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2663e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB          *p_t2t  = &rw_cb.tcb.t2t;
2664e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    const tT2T_INIT_TAG *p_ret;
2665e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8               tms;
2666e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS         status  = NFC_STATUS_FAILED;
2667e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    BOOLEAN             b_blank_tag = TRUE;
2668e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2669e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) == NULL)
2670e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2671e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_WARNING1 ("rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the tag!", p_t2t->tag_hdr[0]);
2672a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu        return (NFC_STATUS_FAILED);
2673e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2674e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2675e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != 0)
2676e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2677e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* If OTP tag has valid NDEF Message, cannot format the tag */
2678e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (  (p_t2t->ndef_msg_len > 0)
2679e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            &&(p_ret->b_otp)  )
2680e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2681e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            RW_TRACE_WARNING0 ("rw_t2t_format_tag - Cannot Format a OTP tag with NDEF Message!");
2682e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            return (NFC_STATUS_FAILED);
2683e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2684e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2685e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if (  ((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0) && (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN))
2686e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            ||((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != 0) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO)) )
2687e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2688e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            RW_TRACE_WARNING0 ("rw_t2t_format_tag - Tag not blank to Format!");
2689e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            return (NFC_STATUS_FAILED);
2690e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2691e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
2692e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2693e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            tms = p_t2t->tag_hdr[T2T_CC2_TMS_BYTE];
2694e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            b_blank_tag = FALSE;
2695e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2696e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2697e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2698e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        tms = p_ret->tms;
2699e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2700e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memset (p_t2t->tag_data, 0, T2T_READ_DATA_LEN);
2701e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2702e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!b_blank_tag || !p_ret->b_multi_version)
2703e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2704e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        status = rw_t2t_set_cc (tms);
2705e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2706e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else if (p_ret->version_block != 0)
2707e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2708e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* If Version number is not read, READ it now */
2709e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2710e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2711e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_read (p_ret->version_block)) == NFC_STATUS_OK)
2712e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
2713e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
2714e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2715e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2716e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2717e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2718e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* UID block is the version block */
2719e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
2720e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2721e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_format_tag_rsp (p_t2t->tag_hdr);
2722e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2723e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2724e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
2725e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2726e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2727e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2728e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2729e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         rw_t2t_soft_lock_tag
2730e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2731e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function will soft lock the tag after validating CC.
2732e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2733e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns
2734e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_OK, Command sent to soft lock the tag
2735e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NFC_STATUS_FAILED: otherwise
2736e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2737e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2738e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS rw_t2t_soft_lock_tag (void)
2739e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2740e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
2741e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status  = NFC_STATUS_FAILED;
2742e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       write_block[T2T_BLOCK_SIZE];
2743e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT8       num_locks;
2744e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2745e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* If CC block is read and cc3 is soft locked, reject the command */
2746e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
2747e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2748e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR1 ("rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: %u", p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2749e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
2750e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2751e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2752e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->b_hard_lock)
2753e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2754e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Should have performed NDEF Detection on dynamic memory structure tag, before permanently converting to Read only
2755e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project         * Even when no lock control tlv is present, default lock bytes should be present */
2756e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2757e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) && (p_t2t->num_lockbytes == 0))
2758e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2759e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            RW_TRACE_ERROR0 ("rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard lock the tag");
2760e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            return (NFC_STATUS_FAILED);
2761e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2762e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2763e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* On dynamic memory structure tag, reset all lock bytes status to 'Not Updated' if not in Updated status */
2764e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        num_locks = 0;
2765e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        while (num_locks < p_t2t->num_lockbytes)
2766e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
2767e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED)
2768e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project                p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED;
2769e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            num_locks++;
2770e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
2771e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2772e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2773e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    memcpy (write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE);
2774e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO;
2775e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2776e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate    = RW_T2T_SUBSTATE_WAIT_SET_CC_RO;
2777e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* First Soft lock the tag */
2778e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((status = rw_t2t_write (T2T_CC_BLOCK, write_block)) == NFC_STATUS_OK)
2779e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2780e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->state        = RW_T2T_STATE_SET_TAG_RO;
2781e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->b_read_hdr   = FALSE;
2782e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2783e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2784e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2785e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate     = RW_T2T_SUBSTATE_NONE;
2786e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2787e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
2788e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2789e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2790e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*****************************************************************************
2791e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2792e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         RW_T2tFormatNDef
2793e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2794e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description
2795e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**      Format Tag content
2796e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2797e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns
2798e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**      NFC_STATUS_OK, Command sent to format Tag
2799e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**      NFC_STATUS_FAILED: otherwise
2800e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2801e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*****************************************************************************/
2802e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS RW_T2tFormatNDef (void)
2803e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2804e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB          *p_t2t  = &rw_cb.tcb.t2t;
2805e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS         status  = NFC_STATUS_FAILED;
2806e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2807e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->state != RW_T2T_STATE_IDLE)
2808e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2809e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_WARNING1 ("RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u", p_t2t->state);
2810e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
2811e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2812e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2813e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!p_t2t->b_read_hdr)
2814e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2815e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* If UID is not read, READ it now */
2816e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
2817e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2818e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_read (0)) == NFC_STATUS_OK)
2819e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
2820e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
2821e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2822e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2823e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
28245c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    {
28255c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        if ((status = rw_t2t_format_tag ()) != NFC_STATUS_OK)
28265c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen            p_t2t->b_read_hdr = FALSE;
28275c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    }
2828e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
2829e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2830e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2831e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2832e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2833e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         RW_T2tLocateTlv
2834e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2835e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function is used to perform TLV detection on a Type 2
2836e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  tag, and retrieve the tag's TLV attribute information.
2837e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2838e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Before using this API, the application must call
2839e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  RW_SelectTagType to indicate that a Type 2 tag has been
2840e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  activated.
2841e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2842e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      tlv_type : TLV to detect
2843e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2844e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error status.
2845e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2846e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2847e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS RW_T2tLocateTlv (UINT8 tlv_type)
2848e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2849e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2850e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status;
2851e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      block;
2852e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2853e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->state != RW_T2T_STATE_IDLE)
2854e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2855e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
2856e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_BUSY);
2857e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2858e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2859e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) && (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV))
2860e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2861e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_API1 ("RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type);
2862e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
2863e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2864e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2865e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (tlv_type == TAG_LOCK_CTRL_TLV)
28665c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        &&(p_t2t->b_read_hdr)
2867e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC)  )
2868e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
28695c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        p_t2t->b_read_hdr = FALSE;
2870e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_API1 ("RW_T2tLocateTlv - No Lock tlv in static structure tag, CC[0]: 0x%02x", p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]);
2871e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
2872e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2873e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2874e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (tlv_type == TAG_NDEF_TLV)
2875e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_t2t->b_read_hdr)
2876e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)  )
2877e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
28785c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        p_t2t->b_read_hdr = FALSE;
2879e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_WARNING3 ("RW_T2tLocateTlv - Invalid NDEF Magic Number!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: 0x%02x", p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE], p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2880e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
2881e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2882e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2883e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->work_offset = 0;
2884e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->tlv_detect  = tlv_type;
2885e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2886e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Reset control block variables based on type of tlv to detect */
2887e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (tlv_type == TAG_LOCK_CTRL_TLV)
2888e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2889e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_lockbytes    = 0;
2890e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_lock_tlvs    = 0;
2891e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2892e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else if (tlv_type == TAG_MEM_CTRL_TLV)
2893e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2894e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_mem_tlvs     = 0;
2895e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2896e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else if (tlv_type == TAG_NDEF_TLV)
2897e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2898e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->ndef_msg_offset  = 0;
2899e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_lockbytes    = 0;
2900e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_lock_tlvs    = 0;
2901e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->num_mem_tlvs     = 0;
2902e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->ndef_msg_len     = 0;
2903e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->ndef_status      = T2T_NDEF_NOT_DETECTED;
2904e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2905e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2906e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2907e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->prop_msg_len     = 0;
2908e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2909e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2910e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!p_t2t->b_read_hdr)
2911e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2912e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* First read CC block */
2913e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        block                   = 0;
2914e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_READ_CC;
2915e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2916e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2917e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2918e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Read first data block */
2919e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        block                   = T2T_FIRST_DATA_BLOCK;
2920e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
2921e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2922e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2923e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Start reading tag, looking for the specified TLV */
2924e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK)
2925e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2926e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->state    = RW_T2T_STATE_DETECT_TLV;
2927e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2928e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
2929e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2930e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2931e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2932e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (status);
2933e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2934e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2935e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2936e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2937e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         RW_T2tDetectNDef
2938e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2939e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function is used to perform NDEF detection on a Type 2
2940e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  tag, and retrieve the tag's NDEF attribute information.
2941e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2942e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Before using this API, the application must call
2943e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  RW_SelectTagType to indicate that a Type 2 tag has been
2944e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  activated.
2945e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2946e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      none
2947e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2948e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK,if detect op started.Otherwise,error status.
2949e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2950e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2951c95c79ccb65d82a65b960919077d5c359cf28cedEvan ChutNFC_STATUS RW_T2tDetectNDef (BOOLEAN skip_dyn_locks)
2952e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2953c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2954c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu
2955c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu    p_t2t->skip_dyn_locks = skip_dyn_locks;
2956c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu
2957e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return RW_T2tLocateTlv (TAG_NDEF_TLV);
2958e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
2959e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2960e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
2961e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2962e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         RW_T2tReadNDef
2963e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2964e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Retrieve NDEF contents from a Type2 tag.
2965e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2966e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  The RW_T2T_NDEF_READ_EVT event is used to notify the
2967e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  application after reading the NDEF message.
2968e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2969e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Before using this API, the RW_T2tDetectNDef function must
2970e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  be called to verify that the tag contains NDEF data, and to
2971e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  retrieve the NDEF attributes.
2972e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2973e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Internally, this command will be separated into multiple Tag2
2974e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Read commands (if necessary) - depending on the NDEF Msg size
2975e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2976e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      p_buffer:   The buffer into which to read the NDEF message
2977e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  buf_len:    The length of the buffer
2978e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2979e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
2980e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
2981e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
2982e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS RW_T2tReadNDef (UINT8 *p_buffer, UINT16 buf_len)
2983e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
2984e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
2985e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status = NFC_STATUS_OK;
2986e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      block;
2987e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2988e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->state != RW_T2T_STATE_IDLE)
2989e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2990e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
2991e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
2992e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2993e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
2994e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED)
2995e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
2996e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR0 ("RW_T2tReadNDef - Error: NDEF detection not performed yet");
2997e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
2998e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
2999e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3000e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (buf_len < p_t2t->ndef_msg_len)
3001e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3002e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_WARNING2 ("RW_T2tReadNDef - buffer size: %u  less than NDEF msg sise: %u", buf_len, p_t2t->ndef_msg_len);
3003e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
3004e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3005e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3006e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!p_t2t->ndef_msg_len)
3007e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3008e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_WARNING1 ("RW_T2tReadNDef - NDEF Message length is zero ", p_t2t->ndef_msg_len);
3009e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_NOT_INITIALIZED);
3010e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3011e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3012e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->p_ndef_buffer  = p_buffer;
3013e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->work_offset    = 0;
3014e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3015e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block  = (UINT16) (p_t2t->ndef_msg_offset / T2T_BLOCK_LEN);
3016e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block -= block % T2T_READ_BLOCKS;
3017e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3018e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3019e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3020e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (block == T2T_FIRST_DATA_BLOCK)
3021e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_t2t->b_read_data)  )
3022e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3023e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->state        = RW_T2T_STATE_READ_NDEF;
3024e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->block_read   = T2T_FIRST_DATA_BLOCK;
3025e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_ndef_read_rsp (p_t2t->tag_data);
3026e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3027e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
3028e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3029e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Start reading NDEF Message */
3030e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
3031e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
3032e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->state    = RW_T2T_STATE_READ_NDEF;
3033e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
3034e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3035e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3036e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return (status);
3037e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
3038e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3039e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
3040e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3041e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         RW_T2tWriteNDef
3042e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3043e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      Write NDEF contents to a Type2 tag.
3044e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3045e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Before using this API, the RW_T2tDetectNDef
3046e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  function must be called to verify that the tag contains
3047e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  NDEF data, and to retrieve the NDEF attributes.
3048e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3049e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  The RW_T2T_NDEF_WRITE_EVT callback event will be used to
3050e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  notify the application of the response.
3051e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3052e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Internally, this command will be separated into multiple Tag2
3053e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Write commands (if necessary) - depending on the NDEF Msg size
3054e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3055e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      msg_len:    The length of the buffer
3056e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  p_msg:      The NDEF message to write
3057e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3058e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK,if write was started. Otherwise, error status
3059e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3060e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
3061e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS RW_T2tWriteNDef (UINT16 msg_len, UINT8 *p_msg)
3062e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
3063e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t          = &rw_cb.tcb.t2t;
3064e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    UINT16      block;
3065e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    const       tT2T_INIT_TAG *p_ret;
3066e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3067e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status          = NFC_STATUS_OK;
3068e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3069e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->state != RW_T2T_STATE_IDLE)
3070e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3071e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
3072e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
3073e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3074e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3075e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED)
3076e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3077e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR0 ("RW_T2tWriteNDef - Error: NDEF detection not performed!");
3078e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
3079e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3080e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
30815c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
30825c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    {
30835c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        RW_TRACE_ERROR1 ("RW_T2tWriteNDef - Write access not granted - CC3: %u", p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
30845c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        return (NFC_STATUS_REFUSED);
30855c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    }
30865c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
3087e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Check if there is enough memory on the tag */
3088e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (msg_len > p_t2t->max_ndef_msg_len)
3089e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3090e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR1 ("RW_T2tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t2t->max_ndef_msg_len);
3091e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
3092e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3093e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3094e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* If OTP tag and tag has valid NDEF Message, stop writting new NDEF Message as it may corrupt the tag */
3095e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (p_t2t->ndef_msg_len > 0)
3096e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
3097e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_ret->b_otp)  )
3098e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3099e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_WARNING0 ("RW_T2tWriteNDef - Cannot Overwrite NDEF Message on a OTP tag!");
3100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
3101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->p_new_ndef_buffer = p_msg;
3103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->new_ndef_msg_len  = msg_len;
3104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->work_offset       = 0;
3105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK;
3107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    /* Read first NDEF Block before updating NDEF */
3108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    block = (UINT16) (p_t2t->ndef_header_offset / T2T_BLOCK_LEN);
3110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (  (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS))
3112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        &&(p_t2t->b_read_data)  )
3113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->state        = RW_T2T_STATE_WRITE_NDEF;
3115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->block_read   = block;
3116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        rw_t2t_handle_ndef_write_rsp (&p_t2t->tag_data[(block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN]);
3117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
3119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
3121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->state    = RW_T2T_STATE_WRITE_NDEF;
3122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
3123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
3127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
3128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*******************************************************************************
3130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Function         RW_T2tSetTagReadOnly
3132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Description      This function can be called to set T2 tag as read only.
3134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Parameters:      b_hard_lock:   To indicate hard lock the tag or not
3136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project** Returns          NCI_STATUS_OK, if setting tag as read only was started.
3138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**                  Otherwise, error status.
3139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project**
3140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project*******************************************************************************/
3141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjecttNFC_STATUS RW_T2tSetTagReadOnly (BOOLEAN b_hard_lock)
3142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{
3143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tNFC_STATUS status = NFC_STATUS_FAILED;
3144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
3145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (p_t2t->state != RW_T2T_STATE_IDLE)
3147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        RW_TRACE_ERROR1 ("RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
3149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        return (NFC_STATUS_FAILED);
3150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    p_t2t->b_hard_lock = b_hard_lock;
3153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    if (!p_t2t->b_read_hdr)
3155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    {
3156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        /* Read CC block before configuring tag as Read only */
3157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        p_t2t->substate    = RW_T2T_SUBSTATE_WAIT_READ_CC;
3158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        if ((status = rw_t2t_read ((UINT16) 0)) == NFC_STATUS_OK)
3159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        {
3160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->state    = RW_T2T_STATE_SET_TAG_RO;
3161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        }
3162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project        else
3163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    }
3165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    else
31665c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    {
31675c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        if ((status = rw_t2t_soft_lock_tag ()) != NFC_STATUS_OK)
31685c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen            p_t2t->b_read_hdr = FALSE;
31695c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    }
3170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project    return status;
3172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}
3173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */
3175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project
3176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif /* (NFC_INCLUDED == TRUE) */
3177