blob: 7f0ae4f8ba7135da15e823260553a95347b6a7aa [file] [log] [blame]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001/******************************************************************************
2 *
Evan Chue9629ba2014-01-31 11:18:47 -05003 * Copyright (C) 2010-2014 Broadcom Corporation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004 *
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 the LLCP Data Link Connection Management
22 *
23 ******************************************************************************/
24
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -070025#include <string>
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080026
27#include <android-base/stringprintf.h>
28#include <base/logging.h>
29
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080030#include "bt_types.h"
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080031#include "gki.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080032#include "llcp_defs.h"
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080033#include "llcp_int.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080034#include "nfc_int.h"
35
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080036using android::base::StringPrintf;
37
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080038static tLLCP_STATUS llcp_dlsm_idle(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
39 void* p_data);
40static tLLCP_STATUS llcp_dlsm_w4_remote_resp(tLLCP_DLCB* p_dlcb,
41 tLLCP_DLC_EVENT event,
42 void* p_data);
43static tLLCP_STATUS llcp_dlsm_w4_local_resp(tLLCP_DLCB* p_dlcb,
44 tLLCP_DLC_EVENT event,
45 void* p_data);
46static tLLCP_STATUS llcp_dlsm_connected(tLLCP_DLCB* p_dlcb,
47 tLLCP_DLC_EVENT event, void* p_data);
48static tLLCP_STATUS llcp_dlsm_w4_remote_dm(tLLCP_DLCB* p_dlcb,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -070049 tLLCP_DLC_EVENT event);
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -070050static std::string llcp_dlsm_get_state_name(tLLCP_DLC_STATE state);
51static std::string llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080052
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080053extern bool nfc_debug_enabled;
54extern unsigned char appl_dta_mode_flag;
55
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080056/*******************************************************************************
57**
58** Function llcp_dlsm_execute
59**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -080060** Description This function executes the state machine for data link
61** connection.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080062**
63** Returns tLLCP_STATUS
64**
65*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080066tLLCP_STATUS llcp_dlsm_execute(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
67 void* p_data) {
68 tLLCP_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080069
Ruchi Kandoi6767aec2017-09-26 09:46:26 -070070 DLOG_IF(INFO, nfc_debug_enabled)
71 << StringPrintf("DLC (0x%02X) - state: %s, evt: %s", p_dlcb->local_sap,
72 llcp_dlsm_get_state_name(p_dlcb->state).c_str(),
73 llcp_dlsm_get_event_name(event).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080074
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080075 switch (p_dlcb->state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080076 case LLCP_DLC_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080077 status = llcp_dlsm_idle(p_dlcb, event, p_data);
78 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080079
80 case LLCP_DLC_STATE_W4_REMOTE_RESP:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080081 status = llcp_dlsm_w4_remote_resp(p_dlcb, event, p_data);
82 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080083
84 case LLCP_DLC_STATE_W4_LOCAL_RESP:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080085 status = llcp_dlsm_w4_local_resp(p_dlcb, event, p_data);
86 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080087
88 case LLCP_DLC_STATE_CONNECTED:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080089 status = llcp_dlsm_connected(p_dlcb, event, p_data);
90 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080091
92 case LLCP_DLC_STATE_W4_REMOTE_DM:
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -070093 status = llcp_dlsm_w4_remote_dm(p_dlcb, event);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080094 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080095
96 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080097 status = LLCP_STATUS_FAIL;
98 break;
99 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800100
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800101 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800102}
103
104/*******************************************************************************
105**
106** Function llcp_dlsm_idle
107**
108** Description Data link connection is in idle state
109**
110** Returns tLLCP_STATUS
111**
112*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800113static tLLCP_STATUS llcp_dlsm_idle(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
114 void* p_data) {
115 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
116 tLLCP_SAP_CBACK_DATA data;
117 tLLCP_CONNECTION_PARAMS* p_params;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800118
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800119 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800120 case LLCP_DLC_EVENT_API_CONNECT_REQ:
121
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800122 /* upper layer requests to create data link connection */
123 p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800124
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800125 status = llcp_util_send_connect(p_dlcb, p_params);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800126
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800127 if (status == LLCP_STATUS_SUCCESS) {
128 p_dlcb->local_miu = p_params->miu;
129 p_dlcb->local_rw = p_params->rw;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800130
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800131 /* wait for response from peer device */
132 p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_RESP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800133
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800134 nfc_start_quick_timer(&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
135 (uint32_t)(llcp_cb.lcb.data_link_timeout *
136 QUICK_TIMER_TICKS_PER_SEC) /
137 1000);
138 }
139 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800140
141 case LLCP_DLC_EVENT_PEER_CONNECT_IND:
142
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800143 /* peer device requests to create data link connection */
144 p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800145
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800146 if (p_params->miu > llcp_cb.lcb.peer_miu) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700147 LOG(WARNING) << StringPrintf(
148 "Peer sent data link MIU bigger than peer's "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800149 "link MIU");
150 p_params->miu = llcp_cb.lcb.peer_miu;
151 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800152
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800153 data.connect_ind.event = LLCP_SAP_EVT_CONNECT_IND;
154 data.connect_ind.remote_sap = p_dlcb->remote_sap;
155 data.connect_ind.local_sap = p_dlcb->local_sap;
156 data.connect_ind.miu = p_params->miu;
157 data.connect_ind.rw = p_params->rw;
158 data.connect_ind.p_service_name = p_params->sn;
159 data.connect_ind.server_sap = p_dlcb->local_sap;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800160
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800161 p_dlcb->remote_miu = p_params->miu;
162 p_dlcb->remote_rw = p_params->rw;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800163
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700164 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
165 "Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800166
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800167 /* wait for response from upper layer */
168 p_dlcb->state = LLCP_DLC_STATE_W4_LOCAL_RESP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800169
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800170 nfc_start_quick_timer(&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
171 (uint32_t)(llcp_cb.lcb.data_link_timeout *
172 QUICK_TIMER_TICKS_PER_SEC) /
173 1000);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800174
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800175 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800176
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800177 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800178
179 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700180 LOG(ERROR) << StringPrintf("Unexpected event");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800181 status = LLCP_STATUS_FAIL;
182 break;
183 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800184
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800185 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800186}
187
188/*******************************************************************************
189**
190** Function llcp_dlsm_w4_remote_resp
191**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800192** Description data link connection is waiting for connection confirm from
193** peer
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800194**
195** Returns tLLCP_STATUS
196**
197*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800198static tLLCP_STATUS llcp_dlsm_w4_remote_resp(tLLCP_DLCB* p_dlcb,
199 tLLCP_DLC_EVENT event,
200 void* p_data) {
201 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
202 tLLCP_SAP_CBACK_DATA data;
203 tLLCP_CONNECTION_PARAMS* p_params;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800204
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800205 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800206 case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
207
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800208 /* peer device accepted data link connection */
209 nfc_stop_quick_timer(&p_dlcb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800210
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800211 p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800212
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800213 /* data link MIU must be up to link MIU */
214 if (p_params->miu > llcp_cb.lcb.peer_miu) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700215 LOG(WARNING) << StringPrintf(
216 "Peer sent data link MIU bigger than "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800217 "peer's link MIU");
218 p_params->miu = llcp_cb.lcb.peer_miu;
219 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800220
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800221 p_dlcb->remote_miu = p_params->miu;
222 p_dlcb->remote_rw = p_params->rw;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800223
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700224 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
225 "Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800226
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800227 p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
228 llcp_util_adjust_dl_rx_congestion();
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800229
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800230 data.connect_resp.event = LLCP_SAP_EVT_CONNECT_RESP;
231 data.connect_resp.remote_sap = p_dlcb->remote_sap;
232 data.connect_resp.local_sap = p_dlcb->local_sap;
233 data.connect_resp.miu = p_params->miu;
234 data.connect_resp.rw = p_params->rw;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800235
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800236 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800237
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800238 if (llcp_cb.overall_rx_congested) {
239 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
240 }
241 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800242
243 case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
244 case LLCP_DLC_EVENT_TIMEOUT:
245
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800246 /* peer device rejected connection or didn't respond */
247 data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
248 data.disconnect_resp.local_sap = p_dlcb->local_sap;
249 data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
250 data.disconnect_resp.reason = *((uint8_t*)p_data);
251 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800252
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800253 /* stop timer, flush any pending data in queue and deallocate control
254 * block */
255 llcp_util_deallocate_data_link(p_dlcb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800256
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800257 llcp_util_adjust_dl_rx_congestion();
258 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800259
260 case LLCP_DLC_EVENT_FRAME_ERROR:
261 case LLCP_DLC_EVENT_LINK_ERROR:
262
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800263 /* received bad frame or link is deactivated */
264 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
265 data.disconnect_ind.local_sap = p_dlcb->local_sap;
266 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
267 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800268
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800269 llcp_util_deallocate_data_link(p_dlcb);
270 llcp_util_adjust_dl_rx_congestion();
271 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800272
273 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700274 LOG(ERROR) << StringPrintf("Unexpected event");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800275 status = LLCP_STATUS_FAIL;
276 break;
277 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800278
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800279 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800280}
281
282/*******************************************************************************
283**
284** Function llcp_dlsm_w4_local_resp
285**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800286** Description data link connection is waiting for connection confirm from
287** application
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800288**
289** Returns tLLCP_STATUS
290**
291*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800292static tLLCP_STATUS llcp_dlsm_w4_local_resp(tLLCP_DLCB* p_dlcb,
293 tLLCP_DLC_EVENT event,
294 void* p_data) {
295 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
296 tLLCP_CONNECTION_PARAMS* p_params;
297 tLLCP_SAP_CBACK_DATA data;
298 uint8_t reason;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800299
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800300 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800301 case LLCP_DLC_EVENT_API_CONNECT_CFM:
302
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800303 /* upper layer accepted data link connection */
304 nfc_stop_quick_timer(&p_dlcb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800305
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800306 p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800307
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800308 p_dlcb->local_miu = p_params->miu;
309 p_dlcb->local_rw = p_params->rw;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800310
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800311 p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800312
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800313 if (llcp_cb.overall_rx_congested) {
314 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
315 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800316
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800317 status = llcp_util_send_cc(p_dlcb, p_params);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800318
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800319 if (status == LLCP_STATUS_SUCCESS) {
320 llcp_util_adjust_dl_rx_congestion();
321 } else {
322 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
323 data.disconnect_ind.local_sap = p_dlcb->local_sap;
324 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
325 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800326
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800327 llcp_util_deallocate_data_link(p_dlcb);
328 }
329 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800330
331 case LLCP_DLC_EVENT_API_CONNECT_REJECT:
332 case LLCP_DLC_EVENT_TIMEOUT:
333
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800334 if (event == LLCP_DLC_EVENT_TIMEOUT)
335 reason = LLCP_SAP_DM_REASON_TEMP_REJECT_THIS;
336 else
337 reason = *((uint8_t*)p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800338
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800339 /* upper layer rejected connection or didn't respond */
340 llcp_util_send_dm(p_dlcb->remote_sap, p_dlcb->local_sap, reason);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800341
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800342 /* stop timer, flush any pending data in queue and deallocate control
343 * block */
344 llcp_util_deallocate_data_link(p_dlcb);
345 llcp_util_adjust_dl_rx_congestion();
346 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800347
348 case LLCP_DLC_EVENT_FRAME_ERROR:
349 case LLCP_DLC_EVENT_LINK_ERROR:
350
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800351 /* received bad frame or link is deactivated */
352 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
353 data.disconnect_ind.local_sap = p_dlcb->local_sap;
354 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
355 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800356
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800357 llcp_util_deallocate_data_link(p_dlcb);
358 llcp_util_adjust_dl_rx_congestion();
359 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800360
361 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700362 LOG(ERROR) << StringPrintf("Unexpected event");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800363 status = LLCP_STATUS_FAIL;
364 break;
365 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800366
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800367 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800368}
369
370/*******************************************************************************
371**
372** Function llcp_dlsm_connected
373**
374** Description data link connection is connected
375**
376** Returns tLLCP_STATUS
377**
378*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800379static tLLCP_STATUS llcp_dlsm_connected(tLLCP_DLCB* p_dlcb,
380 tLLCP_DLC_EVENT event, void* p_data) {
381 bool flush;
382 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
383 tLLCP_SAP_CBACK_DATA data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800384
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800385 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800386 case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
387
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800388 /* upper layer requests to disconnect */
389 flush = *(bool*)(p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800390
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800391 /*
392 ** if upper layer asks to discard any pending data
393 ** or there is no pending data/ack to send and it is not waiting for ack
394 */
395 if ((flush) || ((p_dlcb->i_xmit_q.count == 0) &&
396 (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
397 (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq))) {
398 /* wait for disconnect response */
399 p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_DM;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800400
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800401 llcp_util_send_disc(p_dlcb->remote_sap, p_dlcb->local_sap);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800402
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800403 nfc_start_quick_timer(&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
404 (uint32_t)(llcp_cb.lcb.data_link_timeout *
405 QUICK_TIMER_TICKS_PER_SEC) /
406 1000);
407 } else {
408 /* set flag to send DISC when tx queue is empty */
409 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_DISC;
410 }
411 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800412
413 case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
414
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800415 /* peer device requests to disconnect */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800416
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800417 /* send disconnect response and notify upper layer */
418 llcp_util_send_dm(p_dlcb->remote_sap, p_dlcb->local_sap,
419 LLCP_SAP_DM_REASON_RESP_DISC);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800420
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800421 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
422 data.disconnect_ind.local_sap = p_dlcb->local_sap;
423 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
424 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800425
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800426 llcp_util_deallocate_data_link(p_dlcb);
427 llcp_util_adjust_dl_rx_congestion();
428 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800429
430 case LLCP_DLC_EVENT_API_DATA_REQ:
431
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800432 /* upper layer requests to send data */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800433
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800434 /* if peer device can receive data */
435 if (p_dlcb->remote_rw) {
436 /* enqueue data and check if data can be sent */
437 GKI_enqueue(&p_dlcb->i_xmit_q, p_data);
438 llcp_cb.total_tx_i_pdu++;
439
440 llcp_link_check_send_data();
441
442 if ((p_dlcb->is_tx_congested) || (llcp_cb.overall_tx_congested) ||
443 (p_dlcb->remote_busy) ||
444 (p_dlcb->i_xmit_q.count >=
445 p_dlcb->remote_rw)) /*if enough data to send next round */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800446 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700447 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
448 "Data link (SSAP:DSAP=0x%X:0x%X) "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800449 "congested: xmit_q.count=%d",
450 p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800451
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800452 /* set congested here so overall congestion check routine will not
453 * report event again */
454 p_dlcb->is_tx_congested = true;
455 status = LLCP_STATUS_CONGESTED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800456 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800457 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700458 LOG(ERROR) << StringPrintf("Remote RW is zero: discard data");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800459 /* buffer will be freed when returned to API function */
460 status = LLCP_STATUS_FAIL;
461 }
462 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800463
464 case LLCP_DLC_EVENT_PEER_DATA_IND:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800465 /* peer device sends data so notify upper layer to read data from data
466 * link connection */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800467
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800468 data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
469 data.data_ind.local_sap = p_dlcb->local_sap;
470 data.data_ind.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
471 data.data_ind.remote_sap = p_dlcb->remote_sap;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800472
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800473 (*p_dlcb->p_app_cb->p_app_cback)(&data);
474 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800475
476 case LLCP_DLC_EVENT_FRAME_ERROR:
477 case LLCP_DLC_EVENT_LINK_ERROR:
478
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800479 /* received bad frame or link is deactivated */
480 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
481 data.disconnect_ind.local_sap = p_dlcb->local_sap;
482 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
483 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800484
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800485 llcp_util_deallocate_data_link(p_dlcb);
486 llcp_util_adjust_dl_rx_congestion();
487 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800488
489 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700490 LOG(ERROR) << StringPrintf("Unexpected event");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800491 status = LLCP_STATUS_FAIL;
492 break;
493 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800494
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800495 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800496}
497
498/*******************************************************************************
499**
500** Function llcp_dlsm_w4_remote_dm
501**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800502** Description data link connection is waiting for disconnection confirm
503** from peer
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800504**
505** Returns tLLCP_STATUS
506**
507*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800508static tLLCP_STATUS llcp_dlsm_w4_remote_dm(tLLCP_DLCB* p_dlcb,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700509 tLLCP_DLC_EVENT event) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800510 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
511 tLLCP_SAP_CBACK_DATA data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800512
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800513 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800514 case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
515 case LLCP_DLC_EVENT_TIMEOUT:
516
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800517 /* peer device sends disconnect response or didn't responde */
518 data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
519 data.disconnect_resp.local_sap = p_dlcb->local_sap;
520 data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
521 data.disconnect_resp.reason = LLCP_SAP_DM_REASON_RESP_DISC;
522 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800523
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800524 llcp_util_deallocate_data_link(p_dlcb);
525 llcp_util_adjust_dl_rx_congestion();
526 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800527
528 case LLCP_DLC_EVENT_FRAME_ERROR:
529 case LLCP_DLC_EVENT_LINK_ERROR:
530
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800531 /* received bad frame or link is deactivated */
532 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
533 data.disconnect_ind.local_sap = p_dlcb->local_sap;
534 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
535 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800536
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800537 llcp_util_deallocate_data_link(p_dlcb);
538 llcp_util_adjust_dl_rx_congestion();
539 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800540
541 case LLCP_DLC_EVENT_PEER_DATA_IND:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800542 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800543
544 case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800545 /* it's race condition, send disconnect response and wait for DM */
546 llcp_util_send_dm(p_dlcb->remote_sap, p_dlcb->local_sap,
547 LLCP_SAP_DM_REASON_RESP_DISC);
548 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800549
550 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700551 LOG(ERROR) << StringPrintf("Unexpected event");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800552 status = LLCP_STATUS_FAIL;
553 break;
554 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800555
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800556 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800557}
558
559/*******************************************************************************
560**
561** Function llcp_dlc_find_dlcb_by_local_sap
562**
563** Description Find tLLCP_DLCB by local SAP and remote SAP
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800564** if remote_sap is LLCP_INVALID_SAP, it will return a DLCB
565** which is waiting for CC from peer.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800566**
567** Returns tLLCP_DLCB *
568**
569*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800570tLLCP_DLCB* llcp_dlc_find_dlcb_by_sap(uint8_t local_sap, uint8_t remote_sap) {
571 int i;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800572
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800573 for (i = 0; i < LLCP_MAX_DATA_LINK; i++) {
574 if ((llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE) &&
575 (llcp_cb.dlcb[i].local_sap == local_sap)) {
576 if ((remote_sap == LLCP_INVALID_SAP) &&
577 (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP)) {
578 /* Remote SAP has not been finalized because we are watiing for CC */
579 return (&llcp_cb.dlcb[i]);
580 } else if (llcp_cb.dlcb[i].remote_sap == remote_sap) {
581 return (&llcp_cb.dlcb[i]);
582 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800583 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800584 }
585 return NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800586}
587
588/*******************************************************************************
589**
590** Function llcp_dlc_flush_q
591**
592** Description Free buffers in tx and rx queue in data link
593**
594** Returns void
595**
596*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800597void llcp_dlc_flush_q(tLLCP_DLCB* p_dlcb) {
598 if (p_dlcb) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700599 DLOG_IF(INFO, nfc_debug_enabled)
600 << StringPrintf("local SAP:0x%02X", p_dlcb->local_sap);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800601
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800602 /* Release any held buffers */
603 while (p_dlcb->i_xmit_q.p_first) {
604 GKI_freebuf(GKI_dequeue(&p_dlcb->i_xmit_q));
605 llcp_cb.total_tx_i_pdu--;
606 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800607
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800608 /* discard any received I PDU on data link including in AGF */
609 LLCP_FlushDataLinkRxData(p_dlcb->local_sap, p_dlcb->remote_sap);
610 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700611 LOG(ERROR) << StringPrintf("p_dlcb is NULL");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800612 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800613}
614
615/*******************************************************************************
616**
617** Function llcp_dlc_proc_connect_pdu
618**
619** Description Process CONNECT PDU
620**
621** Returns void
622**
623*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800624static void llcp_dlc_proc_connect_pdu(uint8_t dsap, uint8_t ssap,
625 uint16_t length, uint8_t* p_data) {
626 tLLCP_DLCB* p_dlcb;
627 tLLCP_STATUS status;
628 tLLCP_APP_CB* p_app_cb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800629
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800630 tLLCP_CONNECTION_PARAMS params;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800631
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700632 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800633
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800634 p_app_cb = llcp_util_get_app_cb(dsap);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800635
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800636 if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL) ||
637 ((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700638 LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", dsap);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800639 llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
640 return;
641 }
642
643 /* parse CONNECT PDU and get connection parameters */
644 if (llcp_util_parse_connect(p_data, length, &params) != LLCP_STATUS_SUCCESS) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700645 LOG(ERROR) << StringPrintf("Bad format CONNECT");
Love Khannad7852c92017-06-02 19:55:05 +0530646 /* fix to pass TC_CTO_TAR_BI_02_x (x=5) test case
647 * As per the LLCP test specification v1.2.00 by receiving erroneous SNL PDU
648 * i'e with improper length and service name "urn:nfc:sn:dta-co-echo-in",
649 * the IUT should not send any PDU except SYMM PDU */
650
651 if (appl_dta_mode_flag == 1 &&
652 p_data[1] == strlen((const char*)&p_data[2])) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700653 DLOG_IF(INFO, nfc_debug_enabled)
654 << StringPrintf("%s: Strings are not equal", __func__);
Love Khannad7852c92017-06-02 19:55:05 +0530655 llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
656 } else {
657 llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
658 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800659 return;
660 }
661
662 /* if this is connection by service name */
663 if (dsap == LLCP_SAP_SDP) {
664 /* find registered SAP with service name */
665 if (strlen(params.sn))
666 dsap = llcp_sdp_get_sap_by_name(params.sn, (uint8_t)strlen(params.sn));
667 else {
668 /* if SN type is included without SN */
669 if (params.sn[1] == LLCP_SN_TYPE) {
670 llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
671 } else {
672 /* SDP doesn't accept connection */
673 llcp_util_send_dm(ssap, LLCP_SAP_SDP,
674 LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
675 }
676 return;
677 }
678
679 if (dsap == LLCP_SAP_SDP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700680 LOG(ERROR) << StringPrintf("SDP doesn't accept connection");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800681
682 llcp_util_send_dm(ssap, LLCP_SAP_SDP,
683 LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
684 return;
685 } else if (dsap == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700686 LOG(ERROR) << StringPrintf("Unregistered Service:%s", params.sn);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800687
688 llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
689 return;
690 } else {
691 /* check if this application can support connection-oriented transport */
692 p_app_cb = llcp_util_get_app_cb(dsap);
693
694 if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL) ||
695 ((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700696 LOG(ERROR) << StringPrintf(
697 "SAP(0x%x) doesn't support "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800698 "connection-oriented",
699 dsap);
700 llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800701 return;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800702 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800703 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800704 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800705
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800706 /* check if any data link */
707 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
708 if (p_dlcb) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700709 LOG(ERROR) << StringPrintf("Data link is aleady established");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800710 llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS);
711 } else {
712 /* allocate data link connection control block and notify upper layer
713 * through state machine */
714 p_dlcb = llcp_util_allocate_data_link(dsap, ssap);
715
716 if (p_dlcb) {
717 status =
718 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, &params);
719 if (status != LLCP_STATUS_SUCCESS) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700720 LOG(ERROR) << StringPrintf("Error in state machine");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800721 llcp_util_deallocate_data_link(p_dlcb);
722 }
723 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700724 LOG(ERROR) << StringPrintf("Out of resource");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800725 llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800726 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800727 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800728}
729
730/*******************************************************************************
731**
732** Function llcp_dlc_proc_disc_pdu
733**
734** Description Process DISC PDU
735**
736** Returns void
737**
738*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700739static void llcp_dlc_proc_disc_pdu(uint8_t dsap, uint8_t ssap,
740 uint16_t length) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800741 tLLCP_DLCB* p_dlcb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800742
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700743 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800744
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800745 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
746 if (p_dlcb) {
747 if (length > 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700748 LOG(ERROR) << StringPrintf(
749 "Received extra data (%d bytes) in DISC "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800750 "PDU",
751 length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800752
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800753 llcp_util_send_frmr(p_dlcb,
754 LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
755 LLCP_PDU_DISC_TYPE, 0);
756 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
757 } else {
758 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800759 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800760 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700761 LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800762 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800763}
764
765/*******************************************************************************
766**
767** Function llcp_dlc_proc_cc_pdu
768**
769** Description Process CC PDU
770**
771** Returns void
772**
773*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800774static void llcp_dlc_proc_cc_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
775 uint8_t* p_data) {
776 tLLCP_DLCB* p_dlcb;
777 tLLCP_CONNECTION_PARAMS params;
778 tLLCP_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800779
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700780 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800781
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800782 /* find a DLCB waiting for CC on this local SAP */
783 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
784 if (p_dlcb) {
785 /* The CC may contain a SSAP that is different from the DSAP in the CONNECT
786 */
787 p_dlcb->remote_sap = ssap;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800788
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800789 if (llcp_util_parse_cc(p_data, length, &(params.miu), &(params.rw)) ==
790 LLCP_STATUS_SUCCESS) {
791 status =
792 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
793 if (status != LLCP_STATUS_SUCCESS) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700794 LOG(ERROR) << StringPrintf("Error in state machine");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800795 llcp_util_deallocate_data_link(p_dlcb);
796 }
797 } else {
798 llcp_util_send_frmr(p_dlcb,
799 LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
800 LLCP_PDU_DISC_TYPE, 0);
801 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800802 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800803 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700804 LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800805 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800806}
807
808/*******************************************************************************
809**
810** Function llcp_dlc_proc_dm_pdu
811**
812** Description Process DM PDU
813**
814** Returns void
815**
816*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800817static void llcp_dlc_proc_dm_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
818 uint8_t* p_data) {
819 tLLCP_DLCB* p_dlcb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800820
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700821 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800822
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800823 if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700824 LOG(ERROR) << StringPrintf("Received invalid DM PDU");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800825 } else {
826 if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC) {
827 /* local device initiated disconnecting */
828 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
829 } else {
830 /* peer device rejected connection with any reason */
831 /* find a DLCB waiting for CC on this local SAP */
832 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800833 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800834
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800835 if (p_dlcb) {
836 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP,
837 p_data); /* passing reason */
838 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700839 LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap,
840 ssap);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800841 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800842 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800843}
844
845/*******************************************************************************
846**
847** Function llcp_dlc_proc_i_pdu
848**
849** Description Process I PDU
850**
851** Returns void
852**
853*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800854void llcp_dlc_proc_i_pdu(uint8_t dsap, uint8_t ssap, uint16_t i_pdu_length,
855 uint8_t* p_i_pdu, NFC_HDR* p_msg) {
856 uint8_t *p, *p_dst, send_seq, rcv_seq, error_flags;
857 uint16_t info_len, available_bytes;
858 tLLCP_DLCB* p_dlcb;
859 bool appended;
860 NFC_HDR* p_last_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800861
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700862 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800863
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800864 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800865
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800866 if ((p_dlcb) && (p_dlcb->state == LLCP_DLC_STATE_CONNECTED)) {
867 error_flags = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800868
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800869 if (p_msg) {
870 i_pdu_length = p_msg->len;
871 p_i_pdu = (uint8_t*)(p_msg + 1) + p_msg->offset;
872 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800873
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800874 info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800875
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800876 if (info_len > p_dlcb->local_miu) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700877 LOG(ERROR) << StringPrintf(
878 "exceeding local MIU (%d bytes): got %d "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800879 "bytes SDU",
880 p_dlcb->local_miu, info_len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800881
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800882 error_flags |= LLCP_FRMR_I_ERROR_FLAG;
883 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800884
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800885 /* get sequence numbers */
886 p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800887
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800888 send_seq = LLCP_GET_NS(*p);
889 rcv_seq = LLCP_GET_NR(*p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800890
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700891 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800892 "LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)", send_seq,
893 rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_rx_seq,
894 p_dlcb->sent_ack_seq);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800895
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800896 /* if send sequence number, N(S) is not expected one, V(R) */
897 if (p_dlcb->next_rx_seq != send_seq) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700898 LOG(ERROR) << StringPrintf("Bad N(S) got:%d, expected:%d", send_seq,
899 p_dlcb->next_rx_seq);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800900
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800901 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
902 } else {
903 /* if peer device sends more than our receiving window size */
904 if ((uint8_t)(send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >=
905 p_dlcb->local_rw) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700906 LOG(ERROR) << StringPrintf("Bad N(S):%d >= V(RA):%d + RW(L):%d",
907 send_seq, p_dlcb->sent_ack_seq,
908 p_dlcb->local_rw);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800909
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800910 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
911 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800912 }
913
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800914 /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
915 if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
916 (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
917 (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
918 LLCP_SEQ_MODULO) {
919 error_flags |= LLCP_FRMR_R_ERROR_FLAG;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700920 LOG(ERROR) << StringPrintf("Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
921 rcv_seq, p_dlcb->rcvd_ack_seq,
922 p_dlcb->next_tx_seq);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800923 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800924
925 /* if any error is found */
926 if (error_flags) {
927 llcp_util_send_frmr(p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
928 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
929 } else {
930 /* update local sequence variables */
931 p_dlcb->next_rx_seq = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
932 p_dlcb->rcvd_ack_seq = rcv_seq;
933
934 appended = false;
935
936 /* get last buffer in rx queue */
937 p_last_buf = (NFC_HDR*)GKI_getlast(&p_dlcb->i_rx_q);
938
939 if (p_last_buf) {
940 /* get max length to append at the end of buffer */
941 available_bytes = GKI_get_buf_size(p_last_buf) - NFC_HDR_SIZE -
942 p_last_buf->offset - p_last_buf->len;
943
944 /* if new UI PDU with length can be attached at the end of buffer */
945 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len) {
946 p_dst =
947 (uint8_t*)(p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
948
949 /* add length of information in I PDU */
950 UINT16_TO_BE_STREAM(p_dst, info_len);
951
952 /* copy information of I PDU */
953 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
954
955 memcpy(p_dst, p, info_len);
956
957 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
958
959 if (p_msg) {
960 GKI_freebuf(p_msg);
961 p_msg = NULL;
962 }
963
964 appended = true;
965 }
966 }
967
968 /* if it is not available to append */
969 if (!appended) {
970 /* if it's not from AGF PDU */
971 if (p_msg) {
972 /* add length of information in front of information */
973 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE -
974 LLCP_PDU_AGF_LEN_SIZE;
975 UINT16_TO_BE_STREAM(p, info_len);
976
977 p_msg->offset +=
978 LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
979 p_msg->len -=
980 LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
981 p_msg->layer_specific = 0;
982 } else {
983 p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
984
985 if (p_msg) {
986 p_dst = (uint8_t*)(p_msg + 1);
987
988 /* add length of information in front of information */
989 UINT16_TO_BE_STREAM(p_dst, info_len);
990
991 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
992 memcpy(p_dst, p, info_len);
993
994 p_msg->offset = 0;
995 p_msg->len = LLCP_PDU_AGF_LEN_SIZE + info_len;
996 p_msg->layer_specific = 0;
997 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700998 LOG(ERROR) << StringPrintf("out of buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800999 }
1000 }
1001
1002 /* insert I PDU in rx queue */
1003 if (p_msg) {
1004 GKI_enqueue(&p_dlcb->i_rx_q, p_msg);
1005 p_msg = NULL;
1006 llcp_cb.total_rx_i_pdu++;
1007
1008 llcp_util_check_rx_congested_status();
1009 }
1010 }
1011
1012 p_dlcb->num_rx_i_pdu++;
1013
1014 if ((!p_dlcb->local_busy) && (p_dlcb->num_rx_i_pdu == 1)) {
1015 /* notify rx data is available so upper layer reads data until queue is
1016 * empty */
1017 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1018 }
1019
1020 if ((!p_dlcb->is_rx_congested) &&
1021 (p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001022 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1023 "congested num_rx_i_pdu=%d, "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001024 "rx_congest_threshold=%d",
1025 p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
1026
1027 /* send RNR */
1028 p_dlcb->is_rx_congested = true;
1029 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1030 }
1031 }
1032 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001033 LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001034 llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION);
1035 }
1036
1037 if (p_msg) {
1038 GKI_freebuf(p_msg);
1039 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001040}
1041
1042/*******************************************************************************
1043**
1044** Function llcp_dlc_proc_rr_rnr_pdu
1045**
1046** Description Process RR or RNR PDU
1047**
1048** Returns void
1049**
1050*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001051static void llcp_dlc_proc_rr_rnr_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
1052 uint16_t length, uint8_t* p_data) {
1053 uint8_t rcv_seq, error_flags;
1054 tLLCP_DLCB* p_dlcb;
1055 bool flush = true;
1056 tLLCP_SAP_CBACK_DATA cback_data;
1057 bool old_remote_busy;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001058
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001059 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001060
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001061 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1062 if (p_dlcb != NULL) {
1063 error_flags = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001064
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001065 rcv_seq = LLCP_GET_NR(*p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001066
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001067 if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE) {
1068 error_flags |= LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG;
1069 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001070
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001071 /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
1072 if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
1073 (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
1074 (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
1075 LLCP_SEQ_MODULO) {
1076 error_flags |= LLCP_FRMR_R_ERROR_FLAG;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001077 LOG(ERROR) << StringPrintf(
1078 "Bad N(R):%d valid range [V(SA):%d, "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001079 "V(S):%d]",
1080 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
1081 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001082
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001083 if (error_flags) {
1084 llcp_util_send_frmr(p_dlcb, error_flags, ptype, *p_data);
1085 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1086 } else {
1087 p_dlcb->rcvd_ack_seq = rcv_seq;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001088
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001089 DLOG_IF(INFO, nfc_debug_enabled)
1090 << StringPrintf("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1091 rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1092 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001093 old_remote_busy = p_dlcb->remote_busy;
1094 if (ptype == LLCP_PDU_RNR_TYPE) {
1095 p_dlcb->remote_busy = true;
1096 /* if upper layer hasn't get congestion started notification */
1097 if ((!old_remote_busy) && (!p_dlcb->is_tx_congested)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001098 LOG(WARNING) << StringPrintf(
1099 "Data link (SSAP:DSAP=0x%X:0x%X) "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001100 "congestion start: i_xmit_q.count=%d",
1101 p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001102
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001103 cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1104 cback_data.congest.local_sap = p_dlcb->local_sap;
1105 cback_data.congest.remote_sap = p_dlcb->remote_sap;
1106 cback_data.congest.is_congested = true;
1107 cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001108
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001109 (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001110 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001111 } else {
1112 p_dlcb->remote_busy = false;
1113 /* if upper layer hasn't get congestion ended notification and data link
1114 * is not congested */
1115 if ((old_remote_busy) && (!p_dlcb->is_tx_congested)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001116 LOG(WARNING) << StringPrintf(
1117 "Data link (SSAP:DSAP=0x%X:0x%X) "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001118 "congestion end: i_xmit_q.count=%d",
1119 p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
1120
1121 cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1122 cback_data.congest.local_sap = p_dlcb->local_sap;
1123 cback_data.congest.remote_sap = p_dlcb->remote_sap;
1124 cback_data.congest.is_congested = false;
1125 cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1126
1127 (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
1128 }
1129 }
1130
1131 /* check flag to send DISC when tx queue is empty */
1132 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1133 /* if no pending data and all PDU is acked */
1134 if ((p_dlcb->i_xmit_q.count == 0) &&
1135 (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
1136 (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
1137 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1138 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1139 }
1140 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001141 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001142 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001143 LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001144 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001145}
1146
1147/*******************************************************************************
1148**
1149** Function llcp_dlc_proc_rx_pdu
1150**
1151** Description Process PDU for data link
1152**
1153** Returns void
1154**
1155*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001156void llcp_dlc_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
1157 uint16_t length, uint8_t* p_data) {
1158 tLLCP_DLCB* p_dlcb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001159
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001160 DLOG_IF(INFO, nfc_debug_enabled)
1161 << StringPrintf("DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x", dsap, ptype, ssap);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001162
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001163 if (dsap == LLCP_SAP_LM) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001164 LOG(ERROR) << StringPrintf("Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001165 return;
1166 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001167
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001168 switch (ptype) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001169 case LLCP_PDU_CONNECT_TYPE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001170 llcp_dlc_proc_connect_pdu(dsap, ssap, length, p_data);
1171 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001172
1173 case LLCP_PDU_DISC_TYPE:
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001174 llcp_dlc_proc_disc_pdu(dsap, ssap, length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001175 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001176
1177 case LLCP_PDU_CC_TYPE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001178 llcp_dlc_proc_cc_pdu(dsap, ssap, length, p_data);
1179 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001180
1181 case LLCP_PDU_DM_TYPE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001182 llcp_dlc_proc_dm_pdu(dsap, ssap, length, p_data);
1183 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001184
1185 case LLCP_PDU_FRMR_TYPE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001186 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1187 if (p_dlcb) {
1188 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1189 }
1190 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001191
1192 case LLCP_PDU_RR_TYPE:
1193 case LLCP_PDU_RNR_TYPE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001194 llcp_dlc_proc_rr_rnr_pdu(dsap, ptype, ssap, length, p_data);
1195 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001196
1197 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001198 LOG(ERROR) << StringPrintf("Unexpected PDU type (0x%x)", ptype);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001199
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001200 p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1201 if (p_dlcb) {
1202 llcp_util_send_frmr(p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
1203 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1204 }
1205 break;
1206 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001207}
1208
1209/*******************************************************************************
1210**
1211** Function llcp_dlc_check_to_send_rr_rnr
1212**
1213** Description Send RR or RNR if necessary
1214**
1215** Returns void
1216**
1217*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001218void llcp_dlc_check_to_send_rr_rnr(void) {
1219 uint8_t idx;
1220 bool flush = true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001221
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001222 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001223
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001224 /*
1225 ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs
1226 ** can be aggregated in a received AGF PDU. In this case, this is post
1227 ** processing of AGF PDU to send single RR or RNR after processing all I
1228 ** PDUs in received AGF if there was no I-PDU to carry N(R).
1229 **
1230 ** Send RR or RNR if any change of local busy condition or rx congestion
1231 ** status, or V(RA) is not V(R).
1232 */
1233 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
1234 if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
1235 llcp_util_send_rr_rnr(&(llcp_cb.dlcb[idx]));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001236
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001237 /* check flag to send DISC when tx queue is empty */
1238 if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1239 /* if no pending data and all PDU is acked */
1240 if ((llcp_cb.dlcb[idx].i_xmit_q.count == 0) &&
1241 (llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq) &&
1242 (llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)) {
1243 llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1244 llcp_dlsm_execute(&(llcp_cb.dlcb[idx]),
1245 LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001246 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001247 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001248 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001249 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001250}
1251
1252/*******************************************************************************
1253**
1254** Function llcp_dlc_is_rw_open
1255**
1256** Description check if receive window is open in remote
1257**
1258** Returns TRUE if remote can receive more data
1259**
1260*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001261bool llcp_dlc_is_rw_open(tLLCP_DLCB* p_dlcb) {
1262 if ((uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO <
1263 p_dlcb->remote_rw) {
1264 return true;
1265 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001266 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1267 "Flow Off, V(S):%d, V(SA):%d, RW(R):%d", p_dlcb->next_tx_seq,
1268 p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001269 return false;
1270 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001271}
1272
1273/*******************************************************************************
1274**
1275** Function llcp_dlc_get_next_pdu
1276**
1277** Description Get a PDU from tx queue of data link
1278**
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001279** Returns NFC_HDR*
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001280**
1281*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001282NFC_HDR* llcp_dlc_get_next_pdu(tLLCP_DLCB* p_dlcb) {
1283 NFC_HDR* p_msg = NULL;
1284 bool flush = true;
1285 tLLCP_SAP_CBACK_DATA data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001286
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001287 uint8_t send_seq = p_dlcb->next_tx_seq;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001288
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001289 /* if there is data to send and remote device can receive it */
1290 if ((p_dlcb->i_xmit_q.count) && (!p_dlcb->remote_busy) &&
1291 (llcp_dlc_is_rw_open(p_dlcb))) {
1292 p_msg = (NFC_HDR*)GKI_dequeue(&p_dlcb->i_xmit_q);
1293 llcp_cb.total_tx_i_pdu--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001294
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001295 if (p_msg->offset >= LLCP_MIN_OFFSET) {
1296 /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq,
1297 * V(RA) */
1298 llcp_util_build_info_pdu(p_dlcb, p_msg);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001299
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001300 p_dlcb->next_tx_seq = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001301
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001302 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1303 "LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)", send_seq,
1304 p_dlcb->next_rx_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1305 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001306 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001307 LOG(ERROR) << StringPrintf("offset (%d) must be %d at least",
1308 p_msg->offset, LLCP_MIN_OFFSET);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001309 GKI_freebuf(p_msg);
1310 p_msg = NULL;
1311 }
1312 }
1313
1314 /* if tx queue is empty and all PDU is acknowledged */
1315 if ((p_dlcb->i_xmit_q.count == 0) &&
1316 (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
1317 (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
1318 /* check flag to send DISC */
1319 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1320 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1321 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001322 }
1323
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001324 /* check flag to notify upper layer */
1325 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE) {
1326 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001327
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001328 data.tx_complete.event = LLCP_SAP_EVT_TX_COMPLETE;
1329 data.tx_complete.local_sap = p_dlcb->local_sap;
1330 data.tx_complete.remote_sap = p_dlcb->remote_sap;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001331
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001332 (*p_dlcb->p_app_cb->p_app_cback)(&data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001333 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001334 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001335
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001336 return p_msg;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001337}
1338
1339/*******************************************************************************
1340**
1341** Function llcp_dlc_get_next_pdu_length
1342**
1343** Description return length of PDU which is top in tx queue of data link
1344**
1345** Returns length of PDU
1346**
1347*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001348uint16_t llcp_dlc_get_next_pdu_length(tLLCP_DLCB* p_dlcb) {
1349 NFC_HDR* p_msg;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001350
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001351 /* if there is data to send and remote device can receive it */
1352 if ((p_dlcb->i_xmit_q.count) && (!p_dlcb->remote_busy) &&
1353 (llcp_dlc_is_rw_open(p_dlcb))) {
1354 p_msg = (NFC_HDR*)p_dlcb->i_xmit_q.p_first;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001355
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001356 return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
1357 }
1358 return 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001359}
1360
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001361/*******************************************************************************
1362**
1363** Function llcp_dlsm_get_state_name
1364**
1365** Description This function returns the state name.
1366**
1367** Returns pointer to the name
1368**
1369*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001370static std::string llcp_dlsm_get_state_name(tLLCP_DLC_STATE state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001371 switch (state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001372 case LLCP_DLC_STATE_IDLE:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001373 return "IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001374 case LLCP_DLC_STATE_W4_REMOTE_RESP:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001375 return "W4_REMOTE_RESP";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001376 case LLCP_DLC_STATE_W4_LOCAL_RESP:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001377 return "W4_LOCAL_RESP";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001378 case LLCP_DLC_STATE_CONNECTED:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001379 return "CONNECTED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001380 case LLCP_DLC_STATE_W4_REMOTE_DM:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001381 return "W4_REMOTE_DM";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001382 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001383 return "???? UNKNOWN STATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001384 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001385}
1386
1387/*******************************************************************************
1388**
1389** Function llcp_dlsm_get_event_name
1390**
1391** Description This function returns the event name.
1392**
1393** Returns pointer to the name
1394**
1395*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001396static std::string llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001397 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001398 case LLCP_DLC_EVENT_API_CONNECT_REQ:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001399 return "API_CONNECT_REQ";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001400 case LLCP_DLC_EVENT_API_CONNECT_CFM:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001401 return "API_CONNECT_CFM";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001402 case LLCP_DLC_EVENT_API_CONNECT_REJECT:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001403 return "API_CONNECT_REJECT";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001404 case LLCP_DLC_EVENT_PEER_CONNECT_IND:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001405 return "PEER_CONNECT_IND";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001406 case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001407 return "PEER_CONNECT_CFM";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001408 case LLCP_DLC_EVENT_API_DATA_REQ:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001409 return "API_DATA_REQ";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001410 case LLCP_DLC_EVENT_PEER_DATA_IND:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001411 return "PEER_DATA_IND";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001412 case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001413 return "API_DISCONNECT_REQ";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001414 case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001415 return "PEER_DISCONNECT_IND";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001416 case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001417 return "PEER_DISCONNECT_RESP";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001418 case LLCP_DLC_EVENT_FRAME_ERROR:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001419 return "FRAME_ERROR";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001420 case LLCP_DLC_EVENT_LINK_ERROR:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001421 return "LINK_ERROR";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001422 case LLCP_DLC_EVENT_TIMEOUT:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001423 return "TIMEOUT";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001424 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001425 return "???? UNKNOWN EVENT";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001426 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001427}