1 /******************************************************************************
2  *
3  *  Copyright (C) 2003-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This is the main implementation file for the NFA_RW
22  *
23  ******************************************************************************/
24 #include <string.h>
25 #include "nfa_dm_int.h"
26 #include "nfa_rw_api.h"
27 #include "nfa_rw_int.h"
28 #include "nfa_sys.h"
29 #include "nfa_sys_int.h"
30 
31 /* NFA_RW control block */
32 tNFA_RW_CB nfa_rw_cb;
33 
34 /*****************************************************************************
35 ** Constants and types
36 *****************************************************************************/
37 static const tNFA_SYS_REG nfa_rw_sys_reg = {NULL, nfa_rw_handle_event,
38                                             nfa_rw_sys_disable, NULL};
39 
40 /* NFA_RW actions */
41 const tNFA_RW_ACTION nfa_rw_action_tbl[] = {
42     nfa_rw_handle_op_req,         /* NFA_RW_OP_REQUEST_EVT            */
43     nfa_rw_activate_ntf,          /* NFA_RW_ACTIVATE_NTF_EVT          */
44     nfa_rw_deactivate_ntf,        /* NFA_RW_DEACTIVATE_NTF_EVT        */
45     nfa_rw_presence_check_tick,   /* NFA_RW_PRESENCE_CHECK_TICK_EVT   */
46     nfa_rw_presence_check_timeout /* NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT*/
47 };
48 
49 /*****************************************************************************
50 ** Local function prototypes
51 *****************************************************************************/
52 #if (BT_TRACE_VERBOSE == TRUE)
53 static char* nfa_rw_evt_2_str(uint16_t event);
54 #endif
55 
56 /*******************************************************************************
57 **
58 ** Function         nfa_rw_init
59 **
60 ** Description      Initialize NFA RW
61 **
62 ** Returns          None
63 **
64 *******************************************************************************/
nfa_rw_init(void)65 void nfa_rw_init(void) {
66   NFA_TRACE_DEBUG0("nfa_rw_init ()");
67 
68   /* initialize control block */
69   memset(&nfa_rw_cb, 0, sizeof(tNFA_RW_CB));
70 
71   /* register message handler on NFA SYS */
72   nfa_sys_register(NFA_ID_RW, &nfa_rw_sys_reg);
73 }
74 
75 /*******************************************************************************
76 **
77 ** Function         nfa_rw_sys_disable
78 **
79 ** Description      Clean up rw sub-system
80 **
81 **
82 ** Returns          void
83 **
84 *******************************************************************************/
nfa_rw_sys_disable(void)85 void nfa_rw_sys_disable(void) {
86   /* Return to idle */
87   NFC_SetStaticRfCback(NULL);
88 
89   /* Stop presence check timer (if started) */
90   nfa_rw_stop_presence_check_timer();
91 
92   /* Free scratch buffer if any */
93   nfa_rw_free_ndef_rx_buf();
94 
95   /* Free pending command if any */
96   if (nfa_rw_cb.p_pending_msg) {
97     GKI_freebuf(nfa_rw_cb.p_pending_msg);
98     nfa_rw_cb.p_pending_msg = NULL;
99   }
100 
101   nfa_sys_deregister(NFA_ID_RW);
102 }
103 
104 /*******************************************************************************
105 **
106 ** Function         nfa_rw_proc_disc_evt
107 **
108 ** Description      Called by nfa_dm to handle ACTIVATED/DEACTIVATED  events
109 **
110 ** Returns          void
111 **
112 *******************************************************************************/
nfa_rw_proc_disc_evt(tNFA_DM_RF_DISC_EVT event,tNFC_DISCOVER * p_data,bool excl_rf_not_active)113 void nfa_rw_proc_disc_evt(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data,
114                           bool excl_rf_not_active) {
115   tNFA_RW_MSG msg;
116 
117   switch (event) {
118     case NFA_DM_RF_DISC_ACTIVATED_EVT:
119       msg.hdr.event = NFA_RW_ACTIVATE_NTF_EVT;
120       msg.activate_ntf.p_activate_params = &p_data->activate;
121       msg.activate_ntf.excl_rf_not_active = excl_rf_not_active;
122 
123       nfa_rw_handle_event((NFC_HDR*)&msg);
124       break;
125 
126     case NFA_DM_RF_DISC_DEACTIVATED_EVT:
127       msg.hdr.event = NFA_RW_DEACTIVATE_NTF_EVT;
128 
129       nfa_rw_handle_event((NFC_HDR*)&msg);
130       break;
131 
132     default:
133       break;
134   }
135 }
136 
137 /*******************************************************************************
138 **
139 ** Function         nfa_rw_send_raw_frame
140 **
141 ** Description      Called by nfa_dm to send raw frame
142 **
143 ** Returns          tNFA_STATUS
144 **
145 *******************************************************************************/
nfa_rw_send_raw_frame(NFC_HDR * p_data)146 tNFA_STATUS nfa_rw_send_raw_frame(NFC_HDR* p_data) {
147   tNFA_RW_MSG* p_msg;
148 
149   p_msg = (tNFA_RW_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_RW_MSG));
150   if (p_msg != NULL) {
151     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
152     p_msg->op_req.op = NFA_RW_OP_SEND_RAW_FRAME;
153 
154     p_msg->op_req.params.send_raw_frame.p_data = p_data;
155 
156     if (nfa_rw_handle_event((NFC_HDR*)p_msg)) GKI_freebuf(p_msg);
157 
158     return (NFA_STATUS_OK);
159   }
160   return NFA_STATUS_FAILED;
161 }
162 
163 /*******************************************************************************
164 **
165 ** Function         nfa_rw_handle_event
166 **
167 ** Description      nfa rw main event handling function.
168 **
169 ** Returns          TRUE if caller should free p_msg buffer
170 **
171 *******************************************************************************/
nfa_rw_handle_event(NFC_HDR * p_msg)172 bool nfa_rw_handle_event(NFC_HDR* p_msg) {
173   uint16_t act_idx;
174 
175 #if (BT_TRACE_VERBOSE == TRUE)
176   NFA_TRACE_EVENT3("nfa_rw_handle_event event: %s (0x%02x), flags: %08x",
177                    nfa_rw_evt_2_str(p_msg->event), p_msg->event,
178                    nfa_rw_cb.flags);
179 #else
180   NFA_TRACE_EVENT2("nfa_rw_handle_event event: 0x%x, flags: %08x", p_msg->event,
181                    nfa_rw_cb.flags);
182 #endif
183 
184   /* Get NFA_RW sub-event */
185   act_idx = (p_msg->event & 0x00FF);
186   if (act_idx < (NFA_RW_MAX_EVT & 0xFF)) {
187     return (*nfa_rw_action_tbl[act_idx])((tNFA_RW_MSG*)p_msg);
188   } else {
189     NFA_TRACE_ERROR1("nfa_rw_handle_event: unhandled event 0x%02X",
190                      p_msg->event);
191     return true;
192   }
193 }
194 
195 #if (BT_TRACE_VERBOSE == TRUE)
196 /*******************************************************************************
197 **
198 ** Function         nfa_rw_evt_2_str
199 **
200 ** Description      convert nfa_rw evt to string
201 **
202 *******************************************************************************/
nfa_rw_evt_2_str(uint16_t event)203 static char* nfa_rw_evt_2_str(uint16_t event) {
204   switch (event) {
205     case NFA_RW_OP_REQUEST_EVT:
206       return "NFA_RW_OP_REQUEST_EVT";
207 
208     case NFA_RW_ACTIVATE_NTF_EVT:
209       return "NFA_RW_ACTIVATE_NTF_EVT";
210 
211     case NFA_RW_DEACTIVATE_NTF_EVT:
212       return "NFA_RW_DEACTIVATE_NTF_EVT";
213 
214     case NFA_RW_PRESENCE_CHECK_TICK_EVT:
215       return "NFA_RW_PRESENCE_CHECK_TICK_EVT";
216 
217     case NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT:
218       return "NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT";
219 
220     default:
221       return "Unknown";
222   }
223 }
224 #endif /* BT_TRACE_VERBOSE */
225