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