1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-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 file contains functions that interface with the NFC NCI transport.
22  *  On the receive side, it routes events to the appropriate handler
23  *  (callback). On the transmit side, it manages the command transmission.
24  *
25  ******************************************************************************/
26 #include <android-base/stringprintf.h>
27 #include <base/logging.h>
28 
29 #include "bt_types.h"
30 #include "nfc_api.h"
31 #include "nfc_int.h"
32 
33 using android::base::StringPrintf;
34 
35 extern bool nfc_debug_enabled;
36 
37 /*******************************************************************************
38 **
39 ** Function         nfc_alloc_conn_cb
40 **
41 ** Description      This function is called to allocation a control block for
42 **                  NCI logical connection
43 **
44 ** Returns          The allocated control block or NULL
45 **
46 *******************************************************************************/
nfc_alloc_conn_cb(tNFC_CONN_CBACK * p_cback)47 tNFC_CONN_CB* nfc_alloc_conn_cb(tNFC_CONN_CBACK* p_cback) {
48   int xx, max = NCI_MAX_CONN_CBS;
49   tNFC_CONN_CB* p_conn_cb = nullptr;
50 
51   NFC_CHECK_MAX_CONN();
52   for (xx = 0; xx < max; xx++) {
53     if (nfc_cb.conn_cb[xx].conn_id == NFC_ILLEGAL_CONN_ID) {
54       nfc_cb.conn_cb[xx].conn_id =
55           NFC_PEND_CONN_ID; /* to indicate this cb is used */
56       p_conn_cb = &nfc_cb.conn_cb[xx];
57       p_conn_cb->p_cback = p_cback;
58       break;
59     }
60   }
61   return p_conn_cb;
62 }
63 
64 /*******************************************************************************
65 **
66 ** Function         nfc_set_conn_id
67 **
68 ** Description      This function is called to set the connection id to the
69 **                  connection control block and the id mapping table
70 **
71 ** Returns          void
72 **
73 *******************************************************************************/
nfc_set_conn_id(tNFC_CONN_CB * p_cb,uint8_t conn_id)74 void nfc_set_conn_id(tNFC_CONN_CB* p_cb, uint8_t conn_id) {
75   uint8_t handle;
76 
77   if (p_cb == nullptr) return;
78 
79   p_cb->conn_id = conn_id;
80   handle = (uint8_t)(p_cb - nfc_cb.conn_cb + 1);
81   nfc_cb.conn_id[conn_id] = handle;
82   DLOG_IF(INFO, nfc_debug_enabled)
83       << StringPrintf("nfc_set_conn_id conn_id:%d, handle:%d", conn_id, handle);
84 }
85 
86 /*******************************************************************************
87 **
88 ** Function         nfc_find_conn_cb_by_handle
89 **
90 ** Description      This function is called to locate the control block for
91 **                  loopback test.
92 **
93 ** Returns          The loopback test control block or NULL
94 **
95 *******************************************************************************/
nfc_find_conn_cb_by_handle(uint8_t id)96 tNFC_CONN_CB* nfc_find_conn_cb_by_handle(uint8_t id) {
97   int xx;
98   tNFC_CONN_CB* p_conn_cb = nullptr;
99 
100   for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++) {
101     if (nfc_cb.conn_cb[xx].id == id) {
102       p_conn_cb = &nfc_cb.conn_cb[xx];
103       break;
104     }
105   }
106   return p_conn_cb;
107 }
108 
109 /*******************************************************************************
110 **
111 ** Function         nfc_find_conn_cb_by_conn_id
112 **
113 ** Description      This function is called to locate the control block for
114 **                  the given connection id
115 **
116 ** Returns          The control block or NULL
117 **
118 *******************************************************************************/
nfc_find_conn_cb_by_conn_id(uint8_t conn_id)119 tNFC_CONN_CB* nfc_find_conn_cb_by_conn_id(uint8_t conn_id) {
120   tNFC_CONN_CB* p_conn_cb = nullptr;
121   uint8_t handle;
122   uint8_t id;
123   int xx;
124 
125   if (conn_id == NFC_PEND_CONN_ID) {
126     for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++) {
127       if (nfc_cb.conn_cb[xx].conn_id == NFC_PEND_CONN_ID) {
128         p_conn_cb = &nfc_cb.conn_cb[xx];
129         break;
130       }
131     }
132   } else {
133     id = conn_id & NFC_CONN_ID_ID_MASK;
134     if (id < NFC_MAX_CONN_ID) {
135       handle = nfc_cb.conn_id[id];
136       if (handle > 0) p_conn_cb = &nfc_cb.conn_cb[handle - 1];
137     }
138   }
139 
140   return p_conn_cb;
141 }
142 
143 /*******************************************************************************
144 **
145 ** Function         nfc_free_conn_cb
146 **
147 ** Description      This function is called to free the control block and
148 **                  resources and id mapping table
149 **
150 ** Returns          void
151 **
152 *******************************************************************************/
nfc_free_conn_cb(tNFC_CONN_CB * p_cb)153 void nfc_free_conn_cb(tNFC_CONN_CB* p_cb) {
154   void* p_buf;
155 
156   if (p_cb == nullptr) return;
157 
158   while ((p_buf = GKI_dequeue(&p_cb->rx_q)) != nullptr) GKI_freebuf(p_buf);
159 
160   while ((p_buf = GKI_dequeue(&p_cb->tx_q)) != nullptr) GKI_freebuf(p_buf);
161 
162   if (p_cb->conn_id <= NFC_MAX_CONN_ID) {
163     nfc_cb.conn_id[p_cb->conn_id] = 0;
164   } else {
165     LOG(ERROR) << StringPrintf("invalid conn_id.");
166   }
167   p_cb->p_cback = nullptr;
168   p_cb->conn_id = NFC_ILLEGAL_CONN_ID;
169 }
170 
171 /*******************************************************************************
172 **
173 ** Function         nfc_reset_all_conn_cbs
174 **
175 ** Description      This function is called to free all the control blocks and
176 **                  resources and id mapping table
177 **
178 ** Returns          void
179 **
180 *******************************************************************************/
nfc_reset_all_conn_cbs(void)181 extern void nfc_reset_all_conn_cbs(void) {
182   int xx;
183   tNFC_CONN_CB* p_conn_cb = &nfc_cb.conn_cb[0];
184   tNFC_DEACTIVATE_DEVT deact = tNFC_DEACTIVATE_DEVT();
185 
186   deact.status = NFC_STATUS_NOT_INITIALIZED;
187   deact.type = NFC_DEACTIVATE_TYPE_IDLE;
188   deact.is_ntf = TRUE;
189   for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++, p_conn_cb++) {
190     if (p_conn_cb->conn_id != NFC_ILLEGAL_CONN_ID) {
191       if (p_conn_cb->p_cback) {
192         tNFC_CONN nfc_conn;
193         nfc_conn.deactivate = deact;
194         (*p_conn_cb->p_cback)(p_conn_cb->conn_id, NFC_DEACTIVATE_CEVT,
195                               &nfc_conn);
196       }
197       nfc_free_conn_cb(p_conn_cb);
198     }
199   }
200 }
201