blob: cebabba383200ace5d741124722c0fb0203a22df [file] [log] [blame]
nxpandroidc7611652015-09-23 16:42:05 +05301/******************************************************************************
2 *
3 * Copyright (C) 2010-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 ******************************************************************************/
nxpandroidc7611652015-09-23 16:42:05 +053018
19/******************************************************************************
20 *
21 * This file contains the LLCP Link Management
22 *
23 ******************************************************************************/
24
25#include <string.h>
nxf24591c1cbeab2018-02-21 17:32:26 +053026
27#include <android-base/stringprintf.h>
28#include <base/logging.h>
29
nxpandroidc7611652015-09-23 16:42:05 +053030#include "bt_types.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053031#include "gki.h"
nxpandroidc7611652015-09-23 16:42:05 +053032#include "llcp_defs.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053033#include "llcp_int.h"
nxpandroid81719b12017-03-01 13:03:35 +053034#include "nfa_dm_int.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053035#include "nfc_int.h"
36#include "trace_api.h"
37
38using android::base::StringPrintf;
nxpandroidc7611652015-09-23 16:42:05 +053039
nxpandroid8f6d0532017-07-12 18:25:30 +053040const uint16_t llcp_link_rwt
41 [15] = /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */
42 {
nxf24591c1cbeab2018-02-21 17:32:26 +053043 1, /* WT=0, 302us */
44 1, /* WT=1, 604us */
45 2, /* WT=2, 1208us */
46 3, /* WT=3, 2.4ms */
47 5, /* WT=4, 4.8ms */
48 10, /* WT=5, 9.7ms */
49 20, /* WT=6, 19.3ms */
50 39, /* WT=7, 38.7ms */
51 78, /* WT=8, 77.3ms */
52 155, /* WT=9, 154.6ms */
53 310, /* WT=10, 309.2ms */
54 619, /* WT=11, 618.5ms */
55 1237, /* WT=12, 1237.0ms */
56 2474, /* WT=13, 2474.0ms */
57 4948, /* WT=14, 4948.0ms */
nxpandroidc7611652015-09-23 16:42:05 +053058};
59
nxpandroid8f6d0532017-07-12 18:25:30 +053060static bool llcp_link_parse_gen_bytes(uint8_t gen_bytes_len,
61 uint8_t* p_gen_bytes);
62static bool llcp_link_version_agreement(void);
nxpandroidc7611652015-09-23 16:42:05 +053063
nxpandroid8f6d0532017-07-12 18:25:30 +053064static void llcp_link_send_SYMM(void);
65static void llcp_link_update_status(bool is_activated);
66static void llcp_link_check_congestion(void);
67static void llcp_link_check_uncongested(void);
68static void llcp_link_proc_ui_pdu(uint8_t local_sap, uint8_t remote_sap,
69 uint16_t ui_pdu_length, uint8_t* p_ui_pdu,
70 NFC_HDR* p_msg);
71static void llcp_link_proc_agf_pdu(NFC_HDR* p_msg);
72static void llcp_link_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
73 NFC_HDR* p_msg);
74static void llcp_link_proc_rx_data(NFC_HDR* p_msg);
nxpandroidc7611652015-09-23 16:42:05 +053075
nxpandroid8f6d0532017-07-12 18:25:30 +053076static NFC_HDR* llcp_link_get_next_pdu(bool length_only,
77 uint16_t* p_next_pdu_length);
78static NFC_HDR* llcp_link_build_next_pdu(NFC_HDR* p_agf);
79static void llcp_link_send_to_lower(NFC_HDR* p_msg);
nxpandroidc7611652015-09-23 16:42:05 +053080
nxf24591c1cbeab2018-02-21 17:32:26 +053081#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
nxpandroidc7611652015-09-23 16:42:05 +053082extern tLLCP_TEST_PARAMS llcp_test_params;
83#endif
84
nxf24591c1cbeab2018-02-21 17:32:26 +053085extern bool nfc_debug_enabled;
nxpandroidc7611652015-09-23 16:42:05 +053086extern unsigned char appl_dta_mode_flag;
nxpandroidc7611652015-09-23 16:42:05 +053087
88/* debug functions type */
nxf24591c1cbeab2018-02-21 17:32:26 +053089static std::string llcp_pdu_type(uint8_t ptype);
nxpandroidc7611652015-09-23 16:42:05 +053090
91/*******************************************************************************
92**
93** Function llcp_link_start_inactivity_timer
94**
95** Description This function start LLCP link inactivity timer.
96**
97** Returns void
98**
99*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530100static void llcp_link_start_inactivity_timer(void) {
101 if ((llcp_cb.lcb.inact_timer.in_use == false) &&
102 (llcp_cb.lcb.inact_timeout > 0)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530103 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
104 "Start inactivity_timer: %d ms", llcp_cb.lcb.inact_timeout);
nxpandroidc7611652015-09-23 16:42:05 +0530105
nxpandroid8f6d0532017-07-12 18:25:30 +0530106 nfc_start_quick_timer(&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT,
107 ((uint32_t)llcp_cb.lcb.inact_timeout) *
108 QUICK_TIMER_TICKS_PER_SEC / 1000);
109 }
nxpandroidc7611652015-09-23 16:42:05 +0530110}
111
112/*******************************************************************************
113**
114** Function llcp_link_stop_inactivity_timer
115**
116** Description This function stop LLCP link inactivity timer.
117**
118** Returns void
119**
120*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530121static void llcp_link_stop_inactivity_timer(void) {
122 if (llcp_cb.lcb.inact_timer.in_use) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530123 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Stop inactivity_timer");
nxpandroidc7611652015-09-23 16:42:05 +0530124
nxpandroid8f6d0532017-07-12 18:25:30 +0530125 nfc_stop_quick_timer(&llcp_cb.lcb.inact_timer);
126 }
nxpandroidc7611652015-09-23 16:42:05 +0530127}
128
129/*******************************************************************************
130**
131** Function llcp_link_start_link_timer
132**
nxpandroid8f6d0532017-07-12 18:25:30 +0530133** Description This function starts LLCP link timer (LTO or delay response)
nxpandroidc7611652015-09-23 16:42:05 +0530134**
135** Returns void
136**
137*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530138static void llcp_link_start_link_timer(void) {
139 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) {
140 /* wait for application layer sending data */
141 nfc_start_quick_timer(
142 &llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
143 (((uint32_t)llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) /
144 1000);
145 } else {
146 /* wait for data to receive from remote */
147 nfc_start_quick_timer(
148 &llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
149 ((uint32_t)llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000);
150 }
nxpandroidc7611652015-09-23 16:42:05 +0530151}
152
153/*******************************************************************************
154**
155** Function llcp_link_stop_link_timer
156**
157** Description This function stop LLCP link timer (LTO or delay response).
158**
159** Returns void
160**
161*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530162static void llcp_link_stop_link_timer(void) {
163 nfc_stop_quick_timer(&llcp_cb.lcb.timer);
nxpandroidc7611652015-09-23 16:42:05 +0530164}
165
166/*******************************************************************************
167**
168** Function llcp_link_activate
169**
170** Description Activate LLCP link
171**
172** Returns tLLCP_STATUS
173**
174*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530175tLLCP_STATUS llcp_link_activate(tLLCP_ACTIVATE_CONFIG* p_config) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530176 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530177
nxpandroid8f6d0532017-07-12 18:25:30 +0530178 /* At this point, MAC link activation procedure has been successfully
179 * completed */
nxpandroidc7611652015-09-23 16:42:05 +0530180
nxpandroid8f6d0532017-07-12 18:25:30 +0530181 /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */
182 if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530183 LOG(WARNING) << StringPrintf("max payload size (%d) must be %d bytes",
184 p_config->max_payload_size,
185 LLCP_NCI_MAX_PAYL_SIZE);
nxpandroid8f6d0532017-07-12 18:25:30 +0530186 }
nxpandroidc7611652015-09-23 16:42:05 +0530187
nxpandroid8f6d0532017-07-12 18:25:30 +0530188 /* Processing the parametes that have been received with the MAC link
189 * activation */
190 if (llcp_link_parse_gen_bytes(p_config->gen_bytes_len,
191 p_config->p_gen_bytes) == false) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530192 LOG(ERROR) << StringPrintf("Failed to parse general bytes");
193 /* For LLCP DTA test, In case of bad magic bytes normal p2p communication is
194 * expected,but in case of wrong magic bytes in ATR_REQ, LLC layer will be
195 * disconnected but P2P connection is expected to be in connected state
196 * and non LLC PDU is expected.
197 * As per NFC forum expectation below changes is to send PDU after
198 * disconnect of LLCP PDU.
199 * This is fix for TC_MAC_TAR_BI_01 LLCP test case */
200
201 if (appl_dta_mode_flag == 1 && p_config->is_initiator == FALSE) {
202 NFC_HDR* p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
nxpandroid6154b732016-01-14 20:39:23 +0530203
nxpandroid8f6d0532017-07-12 18:25:30 +0530204 if (p_msg) {
205 /*LLCP test scenario requires non LLC PDU to be sent in case of wrong
nxf24591c1cbeab2018-02-21 17:32:26 +0530206 magic bytes. So sending NFC-DEP pdu with size 1 (0x00)*/
nxpandroid8f6d0532017-07-12 18:25:30 +0530207 p_msg->len = 1;
208 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
nxpandroid6154b732016-01-14 20:39:23 +0530209
nxpandroid8f6d0532017-07-12 18:25:30 +0530210 NFC_SendData(NFC_RF_CONN_ID, p_msg);
211 }
nxpandroid6154b732016-01-14 20:39:23 +0530212 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530213
nxpandroid8f6d0532017-07-12 18:25:30 +0530214 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_FAILED_EVT,
215 LLCP_LINK_BAD_GEN_BYTES);
nxpandroidc7611652015-09-23 16:42:05 +0530216
nxpandroid8f6d0532017-07-12 18:25:30 +0530217 if (p_config->is_initiator == false) {
218 /* repond to any incoming PDU with invalid LLCP PDU */
219 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATION_FAILED;
220 NFC_SetStaticRfCback(llcp_link_connection_cback);
nxpandroidc7611652015-09-23 16:42:05 +0530221 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530222 return LLCP_STATUS_FAIL;
223 }
nxpandroidc7611652015-09-23 16:42:05 +0530224
nxpandroid8f6d0532017-07-12 18:25:30 +0530225 /*
226 ** For the Target device, the scaled value of RWT MUST be less than or equal
227 ** to the scaled value of the LLC Link Timeout (LTO).
228 */
229 if ((p_config->is_initiator) &&
230 (llcp_link_rwt[p_config->waiting_time] > llcp_cb.lcb.peer_lto)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530231 LOG(WARNING) << StringPrintf(
232 "WT (%d, %dms) must be less than or equal to "
nxpandroid8f6d0532017-07-12 18:25:30 +0530233 "LTO (%dms)",
234 p_config->waiting_time, llcp_link_rwt[p_config->waiting_time],
235 llcp_cb.lcb.peer_lto);
236 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530237 /* For DTA mode Peer LTO Should not include TX RX Delay, Just llcp deactivate
nxpandroid8f6d0532017-07-12 18:25:30 +0530238 * after Peer LTO time */
239 if (!appl_dta_mode_flag) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530240 /* extend LTO as much as internally required processing time and propagation
241 * delays */
242 llcp_cb.lcb.peer_lto += LLCP_INTERNAL_TX_DELAY + LLCP_INTERNAL_RX_DELAY;
nxpandroid8f6d0532017-07-12 18:25:30 +0530243 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530244 /* LLCP version number agreement */
245 if (llcp_link_version_agreement() == false) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530246 LOG(ERROR) << StringPrintf("Failed to agree version");
nxpandroid8f6d0532017-07-12 18:25:30 +0530247 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_FAILED_EVT,
248 LLCP_LINK_VERSION_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +0530249
nxpandroid8f6d0532017-07-12 18:25:30 +0530250 if (p_config->is_initiator == false) {
251 /* repond to any incoming PDU with invalid LLCP PDU */
252 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATION_FAILED;
253 NFC_SetStaticRfCback(llcp_link_connection_cback);
nxpandroidc7611652015-09-23 16:42:05 +0530254 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530255 return LLCP_STATUS_FAIL;
256 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530257
nxpandroid8f6d0532017-07-12 18:25:30 +0530258 llcp_cb.lcb.received_first_packet = false;
259 llcp_cb.lcb.is_initiator = p_config->is_initiator;
nxpandroidc7611652015-09-23 16:42:05 +0530260
nxpandroid8f6d0532017-07-12 18:25:30 +0530261 /* reset internal flags */
262 llcp_cb.lcb.flags = 0x00;
nxpandroidc7611652015-09-23 16:42:05 +0530263
nxpandroid8f6d0532017-07-12 18:25:30 +0530264 /* set tx MIU to MIN (MIU of local LLCP, MIU of peer LLCP) */
nxpandroidc7611652015-09-23 16:42:05 +0530265
nxpandroid8f6d0532017-07-12 18:25:30 +0530266 if (llcp_cb.lcb.local_link_miu >= llcp_cb.lcb.peer_miu)
267 llcp_cb.lcb.effective_miu = llcp_cb.lcb.peer_miu;
268 else
269 llcp_cb.lcb.effective_miu = llcp_cb.lcb.local_link_miu;
nxpandroidc7611652015-09-23 16:42:05 +0530270
nxpandroid8f6d0532017-07-12 18:25:30 +0530271 /*
272 ** When entering the normal operation phase, LLCP shall initialize the
273 ** symmetry procedure.
274 */
275 if (llcp_cb.lcb.is_initiator) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530276 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Connected as Initiator");
nxpandroidc7611652015-09-23 16:42:05 +0530277
nxpandroid8f6d0532017-07-12 18:25:30 +0530278 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_init;
279 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
nxpandroidc7611652015-09-23 16:42:05 +0530280
nxpandroid8f6d0532017-07-12 18:25:30 +0530281 if (llcp_cb.lcb.delay_first_pdu_timeout > 0) {
282 /* give a chance to upper layer to send PDU if need */
283 nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_DELAY_FIRST_PDU,
284 (((uint32_t)llcp_cb.lcb.delay_first_pdu_timeout) *
285 QUICK_TIMER_TICKS_PER_SEC) /
286 1000);
287 } else {
288 llcp_link_send_SYMM();
nxpandroidc7611652015-09-23 16:42:05 +0530289 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530290 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +0530291 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Connected as Target");
nxpandroid8f6d0532017-07-12 18:25:30 +0530292 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target;
293 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
nxpandroidc7611652015-09-23 16:42:05 +0530294
nxpandroid8f6d0532017-07-12 18:25:30 +0530295 /* wait for data to receive from remote */
296 llcp_link_start_link_timer();
297 }
nxpandroidc7611652015-09-23 16:42:05 +0530298
nxpandroid8f6d0532017-07-12 18:25:30 +0530299 /*
300 ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set
301 ** data callback because LLCP PDU could be in NCI queue.
302 */
303 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
nxpandroidc7611652015-09-23 16:42:05 +0530304
nxpandroid8f6d0532017-07-12 18:25:30 +0530305 /* LLCP Link Activation completed */
306 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_COMPLETE_EVT,
307 LLCP_LINK_SUCCESS);
nxpandroidc7611652015-09-23 16:42:05 +0530308
nxpandroid8f6d0532017-07-12 18:25:30 +0530309 /* Update link status to service layer */
310 llcp_link_update_status(true);
nxpandroidc7611652015-09-23 16:42:05 +0530311
nxpandroid8f6d0532017-07-12 18:25:30 +0530312 NFC_SetStaticRfCback(llcp_link_connection_cback);
nxpandroidc7611652015-09-23 16:42:05 +0530313
nxpandroid8f6d0532017-07-12 18:25:30 +0530314 return (LLCP_STATUS_SUCCESS);
nxpandroidc7611652015-09-23 16:42:05 +0530315}
316
317/*******************************************************************************
318**
319** Function llcp_deactivate_cleanup
320**
321** Description Clean up for link deactivation
322**
323** Returns void
324**
325*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530326static void llcp_deactivate_cleanup(uint8_t reason) {
327 /* report SDP failure for any pending request */
328 llcp_sdp_proc_deactivation();
nxpandroidc7611652015-09-23 16:42:05 +0530329
nxpandroid8f6d0532017-07-12 18:25:30 +0530330 /* Update link status to service layer */
331 llcp_link_update_status(false);
nxpandroidc7611652015-09-23 16:42:05 +0530332
nxpandroid8f6d0532017-07-12 18:25:30 +0530333 /* We had sent out DISC */
334 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
nxpandroidc7611652015-09-23 16:42:05 +0530335
nxpandroid8f6d0532017-07-12 18:25:30 +0530336 llcp_link_stop_link_timer();
nxpandroidc7611652015-09-23 16:42:05 +0530337
nxpandroid8f6d0532017-07-12 18:25:30 +0530338 /* stop inactivity timer */
339 llcp_link_stop_inactivity_timer();
nxpandroidc7611652015-09-23 16:42:05 +0530340
nxpandroid8f6d0532017-07-12 18:25:30 +0530341 /* Let upper layer deactivate local link */
342 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_DEACTIVATED_EVT, reason);
nxpandroidc7611652015-09-23 16:42:05 +0530343}
344
345/*******************************************************************************
346**
347** Function llcp_link_process_link_timeout
348**
349** Description Process timeout events for LTO, SYMM and deactivating
350**
351** Returns void
352**
353*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530354void llcp_link_process_link_timeout(void) {
355 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
356 if ((llcp_cb.lcb.symm_delay > 0) &&
357 (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)) {
358 /* upper layer doesn't have anything to send */
nxf24591c1cbeab2018-02-21 17:32:26 +0530359 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
360 "LEVT_TIMEOUT in state of "
nxpandroid8f6d0532017-07-12 18:25:30 +0530361 "LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
362 llcp_link_send_SYMM();
nxpandroidc7611652015-09-23 16:42:05 +0530363
nxpandroid8f6d0532017-07-12 18:25:30 +0530364 /* wait for data to receive from remote */
365 llcp_link_start_link_timer();
nxpandroidc7611652015-09-23 16:42:05 +0530366
nxpandroid8f6d0532017-07-12 18:25:30 +0530367 /* start inactivity timer */
368 if (llcp_cb.num_data_link_connection == 0) {
369 llcp_link_start_inactivity_timer();
370 }
371 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +0530372 LOG(ERROR) << StringPrintf(
373 "LEVT_TIMEOUT in state of "
nxpandroid8f6d0532017-07-12 18:25:30 +0530374 "LLCP_LINK_SYMM_REMOTE_XMIT_NEXT");
375 llcp_link_deactivate(LLCP_LINK_TIMEOUT);
nxpandroidc7611652015-09-23 16:42:05 +0530376 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530377 } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) {
378 llcp_deactivate_cleanup(llcp_cb.lcb.link_deact_reason);
nxpandroidc7611652015-09-23 16:42:05 +0530379
nxpandroid8f6d0532017-07-12 18:25:30 +0530380 NFC_SetStaticRfCback(NULL);
381 }
nxpandroidc7611652015-09-23 16:42:05 +0530382}
383
384/*******************************************************************************
385**
386** Function llcp_link_deactivate
387**
388** Description Deactivate LLCP link
389**
390** Returns void
391**
392*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530393void llcp_link_deactivate(uint8_t reason) {
394 uint8_t local_sap, idx;
395 tLLCP_DLCB* p_dlcb;
396 tLLCP_APP_CB* p_app_cb;
nxpandroidc7611652015-09-23 16:42:05 +0530397
nxf24591c1cbeab2018-02-21 17:32:26 +0530398 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("reason = 0x%x", reason);
nxpandroidc7611652015-09-23 16:42:05 +0530399
nxpandroid8f6d0532017-07-12 18:25:30 +0530400 /* Release any held buffers in signaling PDU queue */
401 while (llcp_cb.lcb.sig_xmit_q.p_first)
402 GKI_freebuf(GKI_dequeue(&llcp_cb.lcb.sig_xmit_q));
nxpandroidc7611652015-09-23 16:42:05 +0530403
nxpandroid8f6d0532017-07-12 18:25:30 +0530404 /* Release any held buffers in UI PDU queue */
405 for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++) {
406 p_app_cb = llcp_util_get_app_cb(local_sap);
nxpandroidc7611652015-09-23 16:42:05 +0530407
nxpandroid8f6d0532017-07-12 18:25:30 +0530408 if ((p_app_cb) && (p_app_cb->p_app_cback)) {
409 while (p_app_cb->ui_xmit_q.p_first)
410 GKI_freebuf(GKI_dequeue(&p_app_cb->ui_xmit_q));
nxpandroidc7611652015-09-23 16:42:05 +0530411
nxpandroid8f6d0532017-07-12 18:25:30 +0530412 p_app_cb->is_ui_tx_congested = false;
nxpandroidc7611652015-09-23 16:42:05 +0530413
nxpandroid8f6d0532017-07-12 18:25:30 +0530414 while (p_app_cb->ui_rx_q.p_first)
415 GKI_freebuf(GKI_dequeue(&p_app_cb->ui_rx_q));
nxpandroidc7611652015-09-23 16:42:05 +0530416 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530417 }
nxpandroidc7611652015-09-23 16:42:05 +0530418
nxpandroid8f6d0532017-07-12 18:25:30 +0530419 llcp_cb.total_tx_ui_pdu = 0;
420 llcp_cb.total_rx_ui_pdu = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530421
nxpandroid8f6d0532017-07-12 18:25:30 +0530422 /* Notify all of data link */
423 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
424 if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE) {
425 p_dlcb = &(llcp_cb.dlcb[idx]);
nxpandroidc7611652015-09-23 16:42:05 +0530426
nxpandroid8f6d0532017-07-12 18:25:30 +0530427 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, NULL);
nxpandroidc7611652015-09-23 16:42:05 +0530428 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530429 }
430 llcp_cb.total_tx_i_pdu = 0;
431 llcp_cb.total_rx_i_pdu = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530432
nxpandroid8f6d0532017-07-12 18:25:30 +0530433 llcp_cb.overall_tx_congested = false;
434 llcp_cb.overall_rx_congested = false;
nxf24591c1cbeab2018-02-21 17:32:26 +0530435
nxpandroid8f6d0532017-07-12 18:25:30 +0530436 /* As per the LLCP test specification v1.2.00 for test case TC_LLC_TAR_BV_04
437 * the receiving LLC shall commence sending an LLC PDU to the remote
nxf24591c1cbeab2018-02-21 17:32:26 +0530438 * LLC. So, after IUT receives DISC PDU from LT(remote device), IUT shall
439 * send DISC PDU to LT. appl_dta_mode_flag condition is added to fulfil
440 * above requirement. Only in CR8, the IUT shall acknoweledge with SYMM for
441 * DISC PDU. For other CRx, send DISC PDU.
442 */
nxpandroid8f6d0532017-07-12 18:25:30 +0530443 if ((reason == LLCP_LINK_FRAME_ERROR) ||
444 (reason == LLCP_LINK_LOCAL_INITIATED) ||
nxf24591c1cbeab2018-02-21 17:32:26 +0530445 (appl_dta_mode_flag && reason == LLCP_LINK_REMOTE_INITIATED &&
446 llcp_cb.lcb.is_initiator == false &&
447 (nfa_dm_cb.eDtaMode & 0xF0) != NFA_DTA_CR8)) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530448 /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP
449 */
450 NFC_FlushData(NFC_RF_CONN_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530451
nxpandroid8f6d0532017-07-12 18:25:30 +0530452 llcp_util_send_disc(LLCP_SAP_LM, LLCP_SAP_LM);
nxpandroidc7611652015-09-23 16:42:05 +0530453
nxpandroid8f6d0532017-07-12 18:25:30 +0530454 /* Wait until DISC is sent to peer */
nxf24591c1cbeab2018-02-21 17:32:26 +0530455 DLOG_IF(INFO, nfc_debug_enabled)
456 << StringPrintf("Wait until DISC is sent to peer");
nxpandroidc7611652015-09-23 16:42:05 +0530457
nxpandroid8f6d0532017-07-12 18:25:30 +0530458 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING;
nxpandroidc7611652015-09-23 16:42:05 +0530459
nxpandroid8f6d0532017-07-12 18:25:30 +0530460 if (llcp_cb.lcb.sig_xmit_q.count == 0) {
461 /* if DISC is sent to NFCC, wait for short period for NFCC to send it to
462 * peer */
463 nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
464 ((uint32_t)50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
nxpandroidc7611652015-09-23 16:42:05 +0530465 }
nxpandroidc7611652015-09-23 16:42:05 +0530466
nxpandroid8f6d0532017-07-12 18:25:30 +0530467 llcp_cb.lcb.link_deact_reason = reason;
468 return;
469 } else if ((reason == LLCP_LINK_REMOTE_INITIATED) &&
470 (!llcp_cb.lcb.is_initiator)) {
471 /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */
472 llcp_link_send_SYMM();
473 } else /* for link timeout and interface error */
474 {
475 /* if got RF link loss receiving no LLC PDU from peer */
476 if ((reason == LLCP_LINK_RF_LINK_LOSS_ERR) &&
477 (!(llcp_cb.lcb.flags & LLCP_LINK_FLAGS_RX_ANY_LLC_PDU))) {
478 reason = LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC;
nxpandroidc7611652015-09-23 16:42:05 +0530479 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530480
481 NFC_FlushData(NFC_RF_CONN_ID);
482 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530483
nxpandroid8f6d0532017-07-12 18:25:30 +0530484 llcp_deactivate_cleanup(reason);
nxpandroidc7611652015-09-23 16:42:05 +0530485}
486
487/*******************************************************************************
488**
489** Function llcp_link_parse_gen_bytes
490**
491** Description Check LLCP magic number and get parameters in general bytes
492**
nxf24591c1cbeab2018-02-21 17:32:26 +0530493** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530494**
495*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530496static bool llcp_link_parse_gen_bytes(uint8_t gen_bytes_len,
497 uint8_t* p_gen_bytes) {
498 uint8_t* p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN;
499 uint8_t length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN;
nxpandroidc7611652015-09-23 16:42:05 +0530500
nxpandroid8f6d0532017-07-12 18:25:30 +0530501 if ((gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN) &&
502 (*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0) &&
503 (*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1) &&
504 (*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2)) {
505 /* in case peer didn't include these */
506 llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU;
507 llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS;
nxpandroidc7611652015-09-23 16:42:05 +0530508
nxpandroid8f6d0532017-07-12 18:25:30 +0530509 return (llcp_util_parse_link_params(length, p));
510 } else /* if this is not LLCP */
511 {
nxf24591c1cbeab2018-02-21 17:32:26 +0530512 return false;
nxpandroid8f6d0532017-07-12 18:25:30 +0530513 }
nxpandroidc7611652015-09-23 16:42:05 +0530514
nxf24591c1cbeab2018-02-21 17:32:26 +0530515 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530516}
517
518/*******************************************************************************
519**
520** Function llcp_link_version_agreement
521**
522** Description LLCP version number agreement
523**
nxf24591c1cbeab2018-02-21 17:32:26 +0530524** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530525**
526*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530527static bool llcp_link_version_agreement(void) {
528 uint8_t peer_major_version, peer_minor_version;
nxpandroidc7611652015-09-23 16:42:05 +0530529
nxpandroid8f6d0532017-07-12 18:25:30 +0530530 peer_major_version = LLCP_GET_MAJOR_VERSION(llcp_cb.lcb.peer_version);
531 peer_minor_version = LLCP_GET_MINOR_VERSION(llcp_cb.lcb.peer_version);
nxpandroidc7611652015-09-23 16:42:05 +0530532
nxpandroid8f6d0532017-07-12 18:25:30 +0530533 if (peer_major_version < LLCP_MIN_MAJOR_VERSION) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530534 LOG(ERROR) << StringPrintf(
535 "unsupported peer version number. Peer "
nxpandroid8f6d0532017-07-12 18:25:30 +0530536 "Major Version:%d",
537 peer_major_version);
538 return false;
539 } else {
540 if (peer_major_version == LLCP_VERSION_MAJOR) {
541 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
542 if (peer_minor_version >= LLCP_VERSION_MINOR) {
543 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
544 } else {
545 llcp_cb.lcb.agreed_minor_version = peer_minor_version;
546 }
547 } else if (peer_major_version < LLCP_VERSION_MAJOR) {
548 /* so far we can support backward compatibility */
549 llcp_cb.lcb.agreed_major_version = peer_major_version;
550 llcp_cb.lcb.agreed_minor_version = peer_minor_version;
551 } else {
552 /* let peer (higher major version) decide it */
553 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
554 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
nxpandroidc7611652015-09-23 16:42:05 +0530555 }
nxpandroidc7611652015-09-23 16:42:05 +0530556
nxf24591c1cbeab2018-02-21 17:32:26 +0530557 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530558 "local version:%d.%d, remote version:%d.%d, agreed version:%d.%d",
559 LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR, peer_major_version,
560 peer_minor_version, llcp_cb.lcb.agreed_major_version,
561 llcp_cb.lcb.agreed_minor_version);
nxpandroidc7611652015-09-23 16:42:05 +0530562
nxf24591c1cbeab2018-02-21 17:32:26 +0530563 return true;
nxpandroid8f6d0532017-07-12 18:25:30 +0530564 }
nxpandroidc7611652015-09-23 16:42:05 +0530565}
566
567/*******************************************************************************
568**
569** Function llcp_link_update_status
570**
571** Description Notify all of service layer client link status change
572**
573** Returns void
574**
575*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530576static void llcp_link_update_status(bool is_activated) {
577 tLLCP_SAP_CBACK_DATA data;
578 tLLCP_APP_CB* p_app_cb;
579 uint8_t sap;
nxpandroidc7611652015-09-23 16:42:05 +0530580
nxpandroid8f6d0532017-07-12 18:25:30 +0530581 data.link_status.event = LLCP_SAP_EVT_LINK_STATUS;
582 data.link_status.is_activated = is_activated;
583 data.link_status.is_initiator = llcp_cb.lcb.is_initiator;
nxpandroidc7611652015-09-23 16:42:05 +0530584
nxpandroid8f6d0532017-07-12 18:25:30 +0530585 /* notify all SAP so they can create connection while link is activated */
586 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) {
587 p_app_cb = llcp_util_get_app_cb(sap);
nxpandroidc7611652015-09-23 16:42:05 +0530588
nxpandroid8f6d0532017-07-12 18:25:30 +0530589 if ((p_app_cb) && (p_app_cb->p_app_cback)) {
590 data.link_status.local_sap = sap;
591 p_app_cb->p_app_cback(&data);
nxpandroidc7611652015-09-23 16:42:05 +0530592 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530593 }
nxpandroidc7611652015-09-23 16:42:05 +0530594}
595
596/*******************************************************************************
597**
598** Function llcp_link_check_congestion
599**
600** Description Check overall congestion status
601** Notify to all of upper layer if congested
602**
603** Returns void
604**
605*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530606static void llcp_link_check_congestion(void) {
607 tLLCP_SAP_CBACK_DATA data;
608 tLLCP_APP_CB* p_app_cb;
609 uint8_t sap, idx;
nxpandroidc7611652015-09-23 16:42:05 +0530610
nxpandroid8f6d0532017-07-12 18:25:30 +0530611 if (llcp_cb.overall_tx_congested) {
612 /* already congested so no need to check again */
613 return;
614 }
615
616 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >=
617 llcp_cb.max_num_tx_buff) {
618 /* overall buffer usage is high */
619 llcp_cb.overall_tx_congested = true;
620
nxf24591c1cbeab2018-02-21 17:32:26 +0530621 LOG(WARNING) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530622 "overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
623 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
624
625 data.congest.event = LLCP_SAP_EVT_CONGEST;
626 data.congest.is_congested = true;
627
628 /* notify logical data link congestion status */
629 data.congest.remote_sap = LLCP_INVALID_SAP;
630 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
631
632 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) {
633 p_app_cb = llcp_util_get_app_cb(sap);
634
635 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
636 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
637 /* if already congested then no need to notify again */
638 if (!p_app_cb->is_ui_tx_congested) {
639 p_app_cb->is_ui_tx_congested = true;
640
nxf24591c1cbeab2018-02-21 17:32:26 +0530641 LOG(WARNING) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530642 "Logical link (SAP=0x%X) congestion start: count=%d", sap,
643 p_app_cb->ui_xmit_q.count);
644
645 data.congest.local_sap = sap;
646 p_app_cb->p_app_cback(&data);
647 }
648 }
nxpandroidc7611652015-09-23 16:42:05 +0530649 }
650
nxpandroid8f6d0532017-07-12 18:25:30 +0530651 /* notify data link connection congestion status */
652 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
nxpandroidc7611652015-09-23 16:42:05 +0530653
nxpandroid8f6d0532017-07-12 18:25:30 +0530654 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
655 if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
656 (llcp_cb.dlcb[idx].remote_busy == false) &&
657 (llcp_cb.dlcb[idx].is_tx_congested == false)) {
658 llcp_cb.dlcb[idx].is_tx_congested = true;
nxpandroidc7611652015-09-23 16:42:05 +0530659
nxf24591c1cbeab2018-02-21 17:32:26 +0530660 LOG(WARNING) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530661 "Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d",
662 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
663 llcp_cb.dlcb[idx].i_xmit_q.count);
nxpandroidc7611652015-09-23 16:42:05 +0530664
nxpandroid8f6d0532017-07-12 18:25:30 +0530665 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
666 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
nxpandroidc7611652015-09-23 16:42:05 +0530667
nxpandroid8f6d0532017-07-12 18:25:30 +0530668 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback)(&data);
669 }
nxpandroidc7611652015-09-23 16:42:05 +0530670 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530671 }
nxpandroidc7611652015-09-23 16:42:05 +0530672}
673
674/*******************************************************************************
675**
676** Function llcp_link_check_uncongested
677**
678** Description Check overall congestion status, logical data link and
679** data link connection congestion status
680** Notify to each upper layer if uncongested
681**
682** Returns void
683**
684*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530685static void llcp_link_check_uncongested(void) {
686 tLLCP_SAP_CBACK_DATA data;
687 tLLCP_APP_CB* p_app_cb;
688 uint8_t xx, sap, idx;
nxpandroidc7611652015-09-23 16:42:05 +0530689
nxpandroid8f6d0532017-07-12 18:25:30 +0530690 if (llcp_cb.overall_tx_congested) {
691 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <=
692 llcp_cb.max_num_tx_buff / 2) {
693 /* overall congestion is cleared */
694 llcp_cb.overall_tx_congested = false;
nxpandroidc7611652015-09-23 16:42:05 +0530695
nxf24591c1cbeab2018-02-21 17:32:26 +0530696 LOG(WARNING) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530697 "overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
698 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
699 } else {
700 /* wait until more data packets are sent out */
701 return;
nxpandroidc7611652015-09-23 16:42:05 +0530702 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530703 }
nxpandroidc7611652015-09-23 16:42:05 +0530704
nxpandroid8f6d0532017-07-12 18:25:30 +0530705 data.congest.event = LLCP_SAP_EVT_CONGEST;
706 data.congest.is_congested = false;
nxpandroidc7611652015-09-23 16:42:05 +0530707
nxpandroid8f6d0532017-07-12 18:25:30 +0530708 /* if total number of UI PDU is below threshold */
709 if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff) {
710 /* check and notify logical data link congestion status */
711 data.congest.remote_sap = LLCP_INVALID_SAP;
712 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
nxpandroidc7611652015-09-23 16:42:05 +0530713
714 /*
715 ** start point of uncongested status notification is in round robin
nxpandroid8f6d0532017-07-12 18:25:30 +0530716 ** so each logical data link has equal chance of transmitting.
nxpandroidc7611652015-09-23 16:42:05 +0530717 */
nxpandroid8f6d0532017-07-12 18:25:30 +0530718 sap = llcp_cb.ll_tx_uncongest_ntf_start_sap;
nxpandroidc7611652015-09-23 16:42:05 +0530719
nxpandroid8f6d0532017-07-12 18:25:30 +0530720 for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++) {
721 /* no logical data link on LM and SDP */
722 if (sap > LLCP_SAP_SDP) {
723 p_app_cb = llcp_util_get_app_cb(sap);
nxpandroidc7611652015-09-23 16:42:05 +0530724
nxpandroid8f6d0532017-07-12 18:25:30 +0530725 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
726 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) &&
727 (p_app_cb->is_ui_tx_congested) &&
728 (p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end)) {
729 /* if it was congested but now tx queue count is below threshold */
730 p_app_cb->is_ui_tx_congested = false;
nxpandroidc7611652015-09-23 16:42:05 +0530731
nxf24591c1cbeab2018-02-21 17:32:26 +0530732 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
733 "Logical link (SAP=0x%X) congestion end: count=%d", sap,
734 p_app_cb->ui_xmit_q.count);
nxpandroidc7611652015-09-23 16:42:05 +0530735
nxpandroid8f6d0532017-07-12 18:25:30 +0530736 data.congest.local_sap = sap;
737 p_app_cb->p_app_cback(&data);
nxpandroidc7611652015-09-23 16:42:05 +0530738 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530739 }
740
741 sap = (sap + 1) % LLCP_NUM_SAPS;
nxpandroidc7611652015-09-23 16:42:05 +0530742 }
743
nxpandroid8f6d0532017-07-12 18:25:30 +0530744 /* move start point for next logical data link */
745 for (xx = 0; xx < LLCP_NUM_SAPS; xx++) {
746 sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS;
747
748 if (sap > LLCP_SAP_SDP) {
749 p_app_cb = llcp_util_get_app_cb(sap);
750
751 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
752 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
753 llcp_cb.ll_tx_uncongest_ntf_start_sap = sap;
754 break;
nxpandroidc7611652015-09-23 16:42:05 +0530755 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530756 }
nxpandroidc7611652015-09-23 16:42:05 +0530757 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530758 }
759
760 /* notify data link connection congestion status */
761 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
762
763 /*
764 ** start point of uncongested status notification is in round robin
765 ** so each data link connection has equal chance of transmitting.
766 */
767 idx = llcp_cb.dl_tx_uncongest_ntf_start_idx;
768
769 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
770 /* if it was congested but now tx queue is below threshold (receiving
771 * window) */
772 if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
773 (llcp_cb.dlcb[idx].is_tx_congested) &&
774 (llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2)) {
775 llcp_cb.dlcb[idx].is_tx_congested = false;
776
777 if (llcp_cb.dlcb[idx].remote_busy == false) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530778 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530779 "Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d",
780 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
781 llcp_cb.dlcb[idx].i_xmit_q.count);
782
783 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
784 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
785
786 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback)(&data);
787 }
788 }
789 idx = (idx + 1) % LLCP_MAX_DATA_LINK;
790 }
791
792 /* move start point for next data link connection */
793 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
794 idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK;
795 if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
796 llcp_cb.dl_tx_uncongest_ntf_start_idx = idx;
797 break;
798 }
799 }
nxpandroidc7611652015-09-23 16:42:05 +0530800}
801
802/*******************************************************************************
803**
804** Function llcp_link_send_SYMM
805**
806** Description Send SYMM PDU
807**
808** Returns void
809**
810*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530811static void llcp_link_send_SYMM(void) {
812 NFC_HDR* p_msg;
813 uint8_t* p;
nxf24591c1cbeab2018-02-21 17:32:26 +0530814
nxpandroid8f6d0532017-07-12 18:25:30 +0530815 p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530816
nxpandroid8f6d0532017-07-12 18:25:30 +0530817 if (p_msg) {
818 p_msg->len = LLCP_PDU_SYMM_SIZE;
819 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +0530820
nxpandroid8f6d0532017-07-12 18:25:30 +0530821 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
822 UINT16_TO_BE_STREAM(
823 p, LLCP_GET_PDU_HEADER(LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM));
nxpandroidc7611652015-09-23 16:42:05 +0530824
nxpandroid8f6d0532017-07-12 18:25:30 +0530825 llcp_link_send_to_lower(p_msg);
826 }
nxpandroidc7611652015-09-23 16:42:05 +0530827}
828
829/*******************************************************************************
830**
831** Function llcp_link_send_invalid_pdu
832**
833** Description Send invalid LLC PDU in LLCP_LINK_STATE_ACTIVATION_FAILED
834**
835** Returns void
836**
837*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530838static void llcp_link_send_invalid_pdu(void) {
839 NFC_HDR* p_msg;
840 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530841
nxpandroid8f6d0532017-07-12 18:25:30 +0530842 p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530843
nxpandroid8f6d0532017-07-12 18:25:30 +0530844 if (p_msg) {
845 /* send one byte of 0x00 as invalid LLC PDU */
846 p_msg->len = 1;
847 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +0530848
nxpandroid8f6d0532017-07-12 18:25:30 +0530849 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
850 *p = 0x00;
nxpandroidc7611652015-09-23 16:42:05 +0530851
nxpandroid8f6d0532017-07-12 18:25:30 +0530852 NFC_SendData(NFC_RF_CONN_ID, p_msg);
853 }
nxpandroidc7611652015-09-23 16:42:05 +0530854}
855
856/*******************************************************************************
857**
858** Function llcp_link_check_send_data
859**
860** Description Send PDU to peer
861**
862** Returns void
863**
864*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530865void llcp_link_check_send_data(void) {
866 NFC_HDR* p_pdu;
nxf24591c1cbeab2018-02-21 17:32:26 +0530867
nxpandroid8f6d0532017-07-12 18:25:30 +0530868 /* don't re-enter while processing to prevent out of sequence */
869 if (llcp_cb.lcb.is_sending_data)
870 return;
871 else
872 llcp_cb.lcb.is_sending_data = true;
873
874 /*
875 ** check overall congestion due to high usage of buffer pool
876 ** if congested then notify all of upper layers not to send any more data
877 */
878 llcp_link_check_congestion();
879
880 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT ||
881 (appl_dta_mode_flag &&
882 llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530883 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
884 "in state of "
nxpandroid8f6d0532017-07-12 18:25:30 +0530885 "LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
886
887 p_pdu = llcp_link_build_next_pdu(NULL);
nxpandroidc7611652015-09-23 16:42:05 +0530888
889 /*
nxpandroid8f6d0532017-07-12 18:25:30 +0530890 ** For data link connection,
891 ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in
892 ** this transmission. If there was no I PDU to carry V(RA) and V(RA) is
893 ** not V(R) and it's not congested, then RR PDU will be sent.
894 ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's
895 ** congested, then RNR PDU will be sent.
896 ** If local busy state has been changed then RR or RNR PDU may be sent.
nxpandroidc7611652015-09-23 16:42:05 +0530897 */
nxpandroid8f6d0532017-07-12 18:25:30 +0530898 llcp_dlc_check_to_send_rr_rnr();
nxpandroidc7611652015-09-23 16:42:05 +0530899
nxpandroid8f6d0532017-07-12 18:25:30 +0530900 /* add RR/RNR PDU to be sent if any */
901 p_pdu = llcp_link_build_next_pdu(p_pdu);
nxpandroidc7611652015-09-23 16:42:05 +0530902
nxpandroid8f6d0532017-07-12 18:25:30 +0530903 if (p_pdu != NULL) {
904 llcp_link_send_to_lower(p_pdu);
nxpandroidc7611652015-09-23 16:42:05 +0530905
nxpandroid8f6d0532017-07-12 18:25:30 +0530906 /* stop inactivity timer */
907 llcp_link_stop_inactivity_timer();
nxpandroidc7611652015-09-23 16:42:05 +0530908
nxpandroid8f6d0532017-07-12 18:25:30 +0530909 /* check congestion status after sending out some data */
910 llcp_link_check_uncongested();
911 } else {
912 /* There is no data to send, so send SYMM */
913 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
914 if (llcp_cb.lcb.symm_delay > 0) {
915 /* wait for application layer sending data */
916 llcp_link_start_link_timer();
917 llcp_cb.lcb.is_sending_data = false;
918 return;
919 } else {
920 llcp_link_send_SYMM();
nxpandroidc7611652015-09-23 16:42:05 +0530921
nxpandroid8f6d0532017-07-12 18:25:30 +0530922 /* start inactivity timer */
923 if (llcp_cb.num_data_link_connection == 0) {
924 llcp_link_start_inactivity_timer();
925 }
nxpandroidc7611652015-09-23 16:42:05 +0530926 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530927 } else {
928 llcp_cb.lcb.is_sending_data = false;
929 return;
930 }
nxpandroidc7611652015-09-23 16:42:05 +0530931 }
932
nxpandroid8f6d0532017-07-12 18:25:30 +0530933 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) {
934 /* wait for short period for NFCC to send DISC */
935 nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
936 ((uint32_t)50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
937 } else {
938 /* wait for data to receive from remote */
939 llcp_link_start_link_timer();
940 }
941 }
942
943 llcp_cb.lcb.is_sending_data = false;
nxpandroidc7611652015-09-23 16:42:05 +0530944}
945
946/*******************************************************************************
947**
948** Function llcp_link_proc_ui_pdu
949**
950** Description Process UI PDU from peer device
951**
952** Returns None
953**
954*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530955static void llcp_link_proc_ui_pdu(uint8_t local_sap, uint8_t remote_sap,
956 uint16_t ui_pdu_length, uint8_t* p_ui_pdu,
957 NFC_HDR* p_msg) {
958 bool appended;
959 NFC_HDR* p_last_buf;
960 uint16_t available_bytes;
961 uint8_t* p_dst;
962 tLLCP_APP_CB* p_app_cb;
963 tLLCP_SAP_CBACK_DATA data;
964 tLLCP_DLCB* p_dlcb;
nxpandroidc7611652015-09-23 16:42:05 +0530965
nxpandroid8f6d0532017-07-12 18:25:30 +0530966 p_app_cb = llcp_util_get_app_cb(local_sap);
967 /*if UI PDU sent to SAP with data link connection*/
968 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
969 if (p_dlcb) {
970 llcp_util_send_frmr(p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0);
971 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
972 if (p_msg) {
973 GKI_freebuf(p_msg);
974 }
975 return;
976 }
977
978 /* if application is registered and expecting UI PDU on logical data link */
979 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
980 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530981 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
982 "Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
nxpandroid8f6d0532017-07-12 18:25:30 +0530983
984 /* if this is not from AGF PDU */
985 if (p_msg) {
986 ui_pdu_length = p_msg->len; /* including LLCP header */
987 p_ui_pdu = (uint8_t*)(p_msg + 1) + p_msg->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530988 }
989
nxpandroid8f6d0532017-07-12 18:25:30 +0530990 appended = false;
nxpandroidc7611652015-09-23 16:42:05 +0530991
nxpandroid8f6d0532017-07-12 18:25:30 +0530992 /* get last buffer in rx queue */
993 p_last_buf = (NFC_HDR*)GKI_getlast(&p_app_cb->ui_rx_q);
nxpandroidc7611652015-09-23 16:42:05 +0530994
nxf24591c1cbeab2018-02-21 17:32:26 +0530995 if (p_last_buf) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530996 /* get max length to append at the end of buffer */
997 available_bytes = GKI_get_buf_size(p_last_buf) - NFC_HDR_SIZE -
998 p_last_buf->offset - p_last_buf->len;
nxpandroidc7611652015-09-23 16:42:05 +0530999
nxpandroid8f6d0532017-07-12 18:25:30 +05301000 /* if new UI PDU with length can be attached at the end of buffer */
1001 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length) {
1002 p_dst =
1003 (uint8_t*)(p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
nxpandroidc7611652015-09-23 16:42:05 +05301004
nxpandroid8f6d0532017-07-12 18:25:30 +05301005 /* add length of UI PDU */
1006 UINT16_TO_BE_STREAM(p_dst, ui_pdu_length);
nxpandroidc7611652015-09-23 16:42:05 +05301007
nxpandroid8f6d0532017-07-12 18:25:30 +05301008 /* copy UI PDU with LLCP header */
1009 memcpy(p_dst, p_ui_pdu, ui_pdu_length);
nxpandroidc7611652015-09-23 16:42:05 +05301010
nxpandroid8f6d0532017-07-12 18:25:30 +05301011 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
nxpandroidc7611652015-09-23 16:42:05 +05301012
nxpandroid8f6d0532017-07-12 18:25:30 +05301013 if (p_msg) GKI_freebuf(p_msg);
nxpandroidc7611652015-09-23 16:42:05 +05301014
nxpandroid8f6d0532017-07-12 18:25:30 +05301015 appended = true;
1016 }
nxpandroidc7611652015-09-23 16:42:05 +05301017 }
nxpandroidc7611652015-09-23 16:42:05 +05301018
nxpandroid8f6d0532017-07-12 18:25:30 +05301019 /* if it is not available to append */
1020 if (!appended) {
1021 /* if it's not from AGF PDU */
1022 if (p_msg) {
1023 /* add length of PDU in front of UI PDU (reuse room for NCI header) */
1024 p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE;
1025 UINT16_TO_BE_STREAM(p_ui_pdu, ui_pdu_length);
1026
1027 p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE;
1028 p_msg->len += LLCP_PDU_AGF_LEN_SIZE;
1029 p_msg->layer_specific = 0;
1030 } else {
1031 p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
1032
nxf24591c1cbeab2018-02-21 17:32:26 +05301033 if (p_msg) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301034 p_dst = (uint8_t*)(p_msg + 1);
1035
1036 /* add length of PDU in front of UI PDU */
1037 UINT16_TO_BE_STREAM(p_dst, ui_pdu_length);
1038
1039 memcpy(p_dst, p_ui_pdu, ui_pdu_length);
1040
1041 p_msg->offset = 0;
1042 p_msg->len = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
1043 p_msg->layer_specific = 0;
1044 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301045 LOG(ERROR) << StringPrintf("out of buffer");
nxpandroidc7611652015-09-23 16:42:05 +05301046 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301047 }
1048
1049 /* insert UI PDU in rx queue */
1050 if (p_msg) {
1051 GKI_enqueue(&p_app_cb->ui_rx_q, p_msg);
1052 llcp_cb.total_rx_ui_pdu++;
1053 }
nxpandroidc7611652015-09-23 16:42:05 +05301054 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301055
1056 if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301057 LOG(WARNING) << StringPrintf(
1058 "SAP:0x%x, rx link is congested (%d), "
nxpandroid8f6d0532017-07-12 18:25:30 +05301059 "discard oldest UI PDU",
1060 local_sap, p_app_cb->ui_rx_q.count);
1061
1062 GKI_freebuf(GKI_dequeue(&p_app_cb->ui_rx_q));
1063 llcp_cb.total_rx_ui_pdu--;
1064 }
1065
1066 if ((p_app_cb->ui_rx_q.count == 1) && (appended == false)) {
1067 data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
1068 data.data_ind.local_sap = local_sap;
1069 data.data_ind.remote_sap = remote_sap;
1070 data.data_ind.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
1071 (*p_app_cb->p_app_cback)(&data);
1072 }
1073 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301074 LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", local_sap);
nxpandroid8f6d0532017-07-12 18:25:30 +05301075
1076 if (p_msg) {
1077 GKI_freebuf(p_msg);
1078 }
1079 }
nxpandroidc7611652015-09-23 16:42:05 +05301080}
1081
1082/*******************************************************************************
1083**
1084** Function llcp_link_proc_agf_pdu
1085**
1086** Description Process AGF PDU from peer device
1087**
1088** Returns void
1089**
1090*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301091static void llcp_link_proc_agf_pdu(NFC_HDR* p_agf) {
1092 uint16_t agf_length;
nxf24591c1cbeab2018-02-21 17:32:26 +05301093 uint8_t *p, *p_info, *p_pdu_length;
nxpandroid8f6d0532017-07-12 18:25:30 +05301094 uint16_t pdu_hdr, pdu_length;
1095 uint8_t dsap, ptype, ssap;
nxpandroidc7611652015-09-23 16:42:05 +05301096
nxpandroid8f6d0532017-07-12 18:25:30 +05301097 p_agf->len -= LLCP_PDU_HEADER_SIZE;
1098 p_agf->offset += LLCP_PDU_HEADER_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +05301099
nxpandroid8f6d0532017-07-12 18:25:30 +05301100 /*
1101 ** check integrity of AGF PDU and get number of PDUs in AGF PDU
1102 */
1103 agf_length = p_agf->len;
1104 p = (uint8_t*)(p_agf + 1) + p_agf->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301105
nxpandroid8f6d0532017-07-12 18:25:30 +05301106 while (agf_length > 0) {
1107 if (agf_length > LLCP_PDU_AGF_LEN_SIZE) {
1108 BE_STREAM_TO_UINT16(pdu_length, p);
1109 agf_length -= LLCP_PDU_AGF_LEN_SIZE;
1110 } else {
1111 break;
nxpandroidc7611652015-09-23 16:42:05 +05301112 }
1113
nxpandroid8f6d0532017-07-12 18:25:30 +05301114 if (pdu_length <= agf_length) {
1115 p += pdu_length;
1116 agf_length -= pdu_length;
1117 } else {
1118 break;
nxpandroidc7611652015-09-23 16:42:05 +05301119 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301120 }
nxpandroidc7611652015-09-23 16:42:05 +05301121
nxpandroid8f6d0532017-07-12 18:25:30 +05301122 if (agf_length != 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301123 LOG(ERROR) << StringPrintf("Received invalid AGF PDU");
nxpandroid8f6d0532017-07-12 18:25:30 +05301124 GKI_freebuf(p_agf);
1125 return;
1126 }
nxpandroidc7611652015-09-23 16:42:05 +05301127
nxpandroid8f6d0532017-07-12 18:25:30 +05301128 /*
1129 ** Process PDUs in AGF
1130 */
1131 agf_length = p_agf->len;
1132 p = (uint8_t*)(p_agf + 1) + p_agf->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301133
nxpandroid8f6d0532017-07-12 18:25:30 +05301134 while (agf_length > 0) {
1135 /* get length of PDU */
1136 p_pdu_length = p;
1137 BE_STREAM_TO_UINT16(pdu_length, p);
1138 agf_length -= LLCP_PDU_AGF_LEN_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +05301139
nxpandroid8f6d0532017-07-12 18:25:30 +05301140 /* get DSAP/PTYPE/SSAP */
1141 p_info = p;
1142 BE_STREAM_TO_UINT16(pdu_hdr, p_info);
nxpandroidc7611652015-09-23 16:42:05 +05301143
nxpandroid8f6d0532017-07-12 18:25:30 +05301144 dsap = LLCP_GET_DSAP(pdu_hdr);
1145 ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
1146 ssap = LLCP_GET_SSAP(pdu_hdr);
1147
nxf24591c1cbeab2018-02-21 17:32:26 +05301148 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1149 "Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x "
nxpandroid8f6d0532017-07-12 18:25:30 +05301150 "in AGF",
nxf24591c1cbeab2018-02-21 17:32:26 +05301151 dsap, llcp_pdu_type(ptype).c_str(), ptype, ssap);
nxpandroidc7611652015-09-23 16:42:05 +05301152
nxpandroid8f6d0532017-07-12 18:25:30 +05301153 if ((ptype == LLCP_PDU_DISC_TYPE) && (dsap == LLCP_SAP_LM) &&
1154 (ssap == LLCP_SAP_LM)) {
1155 GKI_freebuf(p_agf);
1156 llcp_link_deactivate(LLCP_LINK_REMOTE_INITIATED);
1157 return;
1158 } else if (ptype == LLCP_PDU_SYMM_TYPE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301159 LOG(ERROR) << StringPrintf("SYMM PDU exchange shall not be in AGF");
nxpandroid8f6d0532017-07-12 18:25:30 +05301160 } else if (ptype == LLCP_PDU_PAX_TYPE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301161 LOG(ERROR) << StringPrintf("PAX PDU exchange shall not be used");
nxpandroid8f6d0532017-07-12 18:25:30 +05301162 } else if (ptype == LLCP_PDU_SNL_TYPE) {
1163 llcp_sdp_proc_snl((uint16_t)(pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
1164 } else if ((ptype == LLCP_PDU_UI_TYPE) &&
1165 (pdu_length > LLCP_PDU_HEADER_SIZE)) {
1166 llcp_link_proc_ui_pdu(dsap, ssap, pdu_length, p, NULL);
1167 } else if (ptype == LLCP_PDU_I_TYPE) {
1168 llcp_dlc_proc_i_pdu(dsap, ssap, pdu_length, p, NULL);
1169 } else /* let data link connection handle PDU */
1170 {
1171 llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
1172 (uint16_t)(pdu_length - LLCP_PDU_HEADER_SIZE),
1173 p_info);
nxpandroidc7611652015-09-23 16:42:05 +05301174 }
1175
nxpandroid8f6d0532017-07-12 18:25:30 +05301176 p += pdu_length;
1177 agf_length -= pdu_length;
1178 }
1179
1180 GKI_freebuf(p_agf);
nxpandroidc7611652015-09-23 16:42:05 +05301181}
1182
1183/*******************************************************************************
1184**
1185** Function llcp_link_proc_rx_pdu
1186**
1187** Description Process received PDU from peer device
1188**
1189** Returns void
1190**
1191*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301192static void llcp_link_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
1193 NFC_HDR* p_msg) {
1194 bool free_buffer = true;
1195 uint8_t* p_data;
nxpandroidc7611652015-09-23 16:42:05 +05301196
nxpandroid8f6d0532017-07-12 18:25:30 +05301197 switch (ptype) {
nxpandroidc7611652015-09-23 16:42:05 +05301198 case LLCP_PDU_PAX_TYPE:
nxf24591c1cbeab2018-02-21 17:32:26 +05301199 LOG(ERROR) << StringPrintf("; PAX PDU exchange shall not be used");
nxpandroid8f6d0532017-07-12 18:25:30 +05301200 break;
nxpandroidc7611652015-09-23 16:42:05 +05301201
1202 case LLCP_PDU_DISC_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301203 if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM)) {
1204 llcp_link_deactivate(LLCP_LINK_REMOTE_INITIATED);
1205 } else {
1206 p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1207 llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
1208 (uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE),
1209 p_data);
1210 }
1211 break;
nxpandroidc7611652015-09-23 16:42:05 +05301212
1213 case LLCP_PDU_SNL_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301214 p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1215 llcp_sdp_proc_snl((uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
1216 break;
nxpandroidc7611652015-09-23 16:42:05 +05301217
1218 case LLCP_PDU_AGF_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301219 llcp_link_proc_agf_pdu(p_msg);
1220 free_buffer = false;
1221 break;
nxpandroidc7611652015-09-23 16:42:05 +05301222
1223 case LLCP_PDU_UI_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301224 llcp_link_proc_ui_pdu(dsap, ssap, 0, NULL, p_msg);
1225 free_buffer = false;
1226 break;
nxpandroidc7611652015-09-23 16:42:05 +05301227
1228 case LLCP_PDU_I_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301229 llcp_dlc_proc_i_pdu(dsap, ssap, 0, NULL, p_msg);
1230 free_buffer = false;
1231 break;
nxpandroidc7611652015-09-23 16:42:05 +05301232
1233 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05301234 p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1235 llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
1236 (uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE),
1237 p_data);
1238 break;
1239 }
nxpandroidc7611652015-09-23 16:42:05 +05301240
nxpandroid8f6d0532017-07-12 18:25:30 +05301241 if (free_buffer) GKI_freebuf(p_msg);
nxpandroidc7611652015-09-23 16:42:05 +05301242}
1243
1244/*******************************************************************************
1245**
1246** Function llcp_link_proc_rx_data
1247**
1248** Description Process received data from NFCC and maintain symmetry state
1249**
1250** Returns void
1251**
1252*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301253static void llcp_link_proc_rx_data(NFC_HDR* p_msg) {
1254 uint8_t* p;
1255 uint16_t pdu_hdr, info_length = 0;
1256 uint8_t dsap, ptype, ssap;
1257 bool free_buffer = true;
1258 bool frame_error = false;
nxpandroidc7611652015-09-23 16:42:05 +05301259
nxpandroid8f6d0532017-07-12 18:25:30 +05301260 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT) {
1261 llcp_link_stop_link_timer();
nxpandroidc7611652015-09-23 16:42:05 +05301262
nxpandroid8f6d0532017-07-12 18:25:30 +05301263 if (llcp_cb.lcb.received_first_packet == false) {
1264 llcp_cb.lcb.received_first_packet = true;
1265 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_FIRST_PACKET_RECEIVED_EVT,
1266 LLCP_LINK_SUCCESS);
1267 }
1268 if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) &&
1269 (llcp_cb.lcb.sig_xmit_q.count == 0)) {
1270 /* this indicates that DISC PDU had been sent out to peer */
1271 /* initiator may wait for SYMM PDU */
1272 if (appl_dta_mode_flag == 0x01)
1273 llcp_util_send_disc(LLCP_SAP_LM, LLCP_SAP_LM);
1274 else
1275 llcp_link_process_link_timeout();
1276 } else {
1277 if (p_msg->len < LLCP_PDU_HEADER_SIZE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301278 LOG(ERROR) << StringPrintf("Received too small PDU: got %d bytes",
1279 p_msg->len);
nxpandroid8f6d0532017-07-12 18:25:30 +05301280 frame_error = true;
1281 } else {
1282 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
1283 BE_STREAM_TO_UINT16(pdu_hdr, p);
1284
1285 dsap = LLCP_GET_DSAP(pdu_hdr);
1286 ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
1287 ssap = LLCP_GET_SSAP(pdu_hdr);
1288
1289 /* get length of information per PDU type */
1290 if ((ptype == LLCP_PDU_I_TYPE) || (ptype == LLCP_PDU_RR_TYPE) ||
1291 (ptype == LLCP_PDU_RNR_TYPE)) {
1292 if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE) {
1293 info_length =
1294 p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
1295 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301296 LOG(ERROR) << StringPrintf(
1297 "Received I/RR/RNR PDU without sequence");
nxpandroid8f6d0532017-07-12 18:25:30 +05301298 frame_error = true;
1299 }
1300 } else {
1301 info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +05301302 }
nxpandroidc7611652015-09-23 16:42:05 +05301303
nxpandroid8f6d0532017-07-12 18:25:30 +05301304 /* check if length of information is bigger than link MIU */
1305 if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu)) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301306 LOG(ERROR) << StringPrintf(
1307 "Received exceeding MIU (%d): got %d bytes SDU",
1308 llcp_cb.lcb.local_link_miu, info_length);
nxpandroidc7611652015-09-23 16:42:05 +05301309
nxpandroid8f6d0532017-07-12 18:25:30 +05301310 frame_error = true;
1311 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301312 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1313 "DSAP:0x%x, PTYPE:%s (0x%x), "
nxpandroid8f6d0532017-07-12 18:25:30 +05301314 "SSAP:0x%x",
nxf24591c1cbeab2018-02-21 17:32:26 +05301315 dsap, llcp_pdu_type(ptype).c_str(), ptype, ssap);
nxpandroidc7611652015-09-23 16:42:05 +05301316
nxpandroid8f6d0532017-07-12 18:25:30 +05301317 if (ptype == LLCP_PDU_SYMM_TYPE) {
1318 if (info_length > 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301319 LOG(ERROR) << StringPrintf(
1320 "Received extra data (%d bytes) in SYMM PDU", info_length);
nxpandroid8f6d0532017-07-12 18:25:30 +05301321 frame_error = true;
nxpandroidc7611652015-09-23 16:42:05 +05301322 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301323 } else {
1324 /* received other than SYMM */
1325 llcp_link_stop_inactivity_timer();
nxpandroidc7611652015-09-23 16:42:05 +05301326
nxpandroid8f6d0532017-07-12 18:25:30 +05301327 llcp_link_proc_rx_pdu(dsap, ptype, ssap, p_msg);
1328 free_buffer = false;
1329 }
nxpandroidc7611652015-09-23 16:42:05 +05301330 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301331 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301332
nxpandroid8f6d0532017-07-12 18:25:30 +05301333 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
nxpandroidc7611652015-09-23 16:42:05 +05301334
nxpandroid8f6d0532017-07-12 18:25:30 +05301335 /* check if any pending packet */
1336 llcp_link_check_send_data();
1337 }
1338 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301339 LOG(ERROR) << StringPrintf("Received PDU in state of SYMM_MUST_XMIT_NEXT");
nxpandroid8f6d0532017-07-12 18:25:30 +05301340 }
1341
1342 if (free_buffer) GKI_freebuf(p_msg);
nxpandroidc7611652015-09-23 16:42:05 +05301343}
1344
1345/*******************************************************************************
1346**
1347** Function llcp_link_get_next_pdu
1348**
1349** Description Get next PDU from link manager or data links w/wo dequeue
1350**
nxf24591c1cbeab2018-02-21 17:32:26 +05301351** Returns pointer of a PDU to send if length_only is FALSE
nxpandroidc7611652015-09-23 16:42:05 +05301352** NULL otherwise
1353**
1354*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301355static NFC_HDR* llcp_link_get_next_pdu(bool length_only,
1356 uint16_t* p_next_pdu_length) {
1357 NFC_HDR* p_msg;
1358 int count, xx;
1359 tLLCP_APP_CB* p_app_cb;
nxpandroidc7611652015-09-23 16:42:05 +05301360
nxpandroid8f6d0532017-07-12 18:25:30 +05301361 /* processing signalling PDU first */
1362 if (llcp_cb.lcb.sig_xmit_q.p_first) {
1363 if (length_only) {
1364 p_msg = (NFC_HDR*)llcp_cb.lcb.sig_xmit_q.p_first;
1365 *p_next_pdu_length = p_msg->len;
1366 return NULL;
1367 } else
1368 p_msg = (NFC_HDR*)GKI_dequeue(&llcp_cb.lcb.sig_xmit_q);
1369
1370 return p_msg;
1371 } else {
1372 /* transmitting logical data link and data link connection equaly */
1373 for (xx = 0; xx < 2; xx++) {
1374 if (!llcp_cb.lcb.ll_served) {
1375 /* Get one from logical link connection */
1376 for (count = 0; count < LLCP_NUM_SAPS; count++) {
1377 /* round robin schedule without priority */
1378 p_app_cb = llcp_util_get_app_cb(llcp_cb.lcb.ll_idx);
1379
1380 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
1381 (p_app_cb->ui_xmit_q.count)) {
1382 if (length_only) {
1383 /* don't alternate next data link to return the same length of PDU
1384 */
1385 p_msg = (NFC_HDR*)p_app_cb->ui_xmit_q.p_first;
1386 *p_next_pdu_length = p_msg->len;
1387 return NULL;
1388 } else {
1389 /* check data link connection first in next time */
1390 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1391
1392 p_msg = (NFC_HDR*)GKI_dequeue(&p_app_cb->ui_xmit_q);
1393 llcp_cb.total_tx_ui_pdu--;
1394
1395 /* this logical link has been served, so start from next logical
1396 * link next time */
1397 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1398
1399 return p_msg;
1400 }
1401 } else {
1402 /* check next logical link connection */
1403 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1404 }
nxpandroidc7611652015-09-23 16:42:05 +05301405 }
nxpandroidc7611652015-09-23 16:42:05 +05301406
nxpandroid8f6d0532017-07-12 18:25:30 +05301407 /* no data, so check data link connection if not checked yet */
1408 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1409 } else {
1410 /* Get one from data link connection */
1411 for (count = 0; count < LLCP_MAX_DATA_LINK; count++) {
1412 /* round robin schedule without priority */
1413 if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE) {
1414 if (length_only) {
1415 *p_next_pdu_length = llcp_dlc_get_next_pdu_length(
1416 &llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
nxpandroidc7611652015-09-23 16:42:05 +05301417
nxpandroid8f6d0532017-07-12 18:25:30 +05301418 if (*p_next_pdu_length > 0) {
1419 /* don't change data link connection to return the same length
1420 * of PDU */
1421 return NULL;
1422 } else {
1423 /* no data, so check next data link connection */
1424 llcp_cb.lcb.dl_idx =
1425 (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1426 }
1427 } else {
1428 p_msg = llcp_dlc_get_next_pdu(&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
nxpandroidc7611652015-09-23 16:42:05 +05301429
nxpandroid8f6d0532017-07-12 18:25:30 +05301430 /* this data link has been served, so start from next data link
1431 * next time */
1432 llcp_cb.lcb.dl_idx =
1433 (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
nxpandroidc7611652015-09-23 16:42:05 +05301434
nxpandroid8f6d0532017-07-12 18:25:30 +05301435 if (p_msg) {
1436 /* serve logical data link next time */
nxpandroidc7611652015-09-23 16:42:05 +05301437 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
nxpandroid8f6d0532017-07-12 18:25:30 +05301438 return p_msg;
1439 }
nxpandroidc7611652015-09-23 16:42:05 +05301440 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301441 } else {
1442 /* check next data link connection */
1443 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1444 }
nxpandroidc7611652015-09-23 16:42:05 +05301445 }
nxpandroidc7611652015-09-23 16:42:05 +05301446
nxpandroid8f6d0532017-07-12 18:25:30 +05301447 /* if all of data link connection doesn't have data to send */
1448 if (count >= LLCP_MAX_DATA_LINK) {
1449 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1450 }
1451 }
1452 }
1453 }
1454
1455 /* nothing to send */
1456 *p_next_pdu_length = 0;
1457 return NULL;
nxpandroidc7611652015-09-23 16:42:05 +05301458}
1459
1460/*******************************************************************************
1461**
1462** Function llcp_link_build_next_pdu
1463**
1464** Description Build a PDU from Link Manager and Data Link
1465** Perform aggregation procedure if necessary
1466**
nxpandroid8f6d0532017-07-12 18:25:30 +05301467** Returns NFC_HDR* if sent any PDU
nxpandroidc7611652015-09-23 16:42:05 +05301468**
1469*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301470static NFC_HDR* llcp_link_build_next_pdu(NFC_HDR* p_pdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301471 NFC_HDR *p_agf = NULL, *p_msg = NULL, *p_next_pdu;
1472 uint8_t *p, ptype;
nxpandroid8f6d0532017-07-12 18:25:30 +05301473 uint16_t next_pdu_length, pdu_hdr;
nxpandroidc7611652015-09-23 16:42:05 +05301474
nxf24591c1cbeab2018-02-21 17:32:26 +05301475 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301476
nxpandroid8f6d0532017-07-12 18:25:30 +05301477 /* add any pending SNL PDU into sig_xmit_q for transmitting */
1478 llcp_sdp_check_send_snl();
nxpandroidc7611652015-09-23 16:42:05 +05301479
nxpandroid8f6d0532017-07-12 18:25:30 +05301480 if (p_pdu) {
1481 /* get PDU type */
1482 p = (uint8_t*)(p_pdu + 1) + p_pdu->offset;
1483 BE_STREAM_TO_UINT16(pdu_hdr, p);
nxpandroidc7611652015-09-23 16:42:05 +05301484
nxpandroid8f6d0532017-07-12 18:25:30 +05301485 ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
nxpandroidc7611652015-09-23 16:42:05 +05301486
nxpandroid8f6d0532017-07-12 18:25:30 +05301487 if (ptype == LLCP_PDU_AGF_TYPE) {
1488 /* add more PDU into this AGF PDU */
1489 p_agf = p_pdu;
1490 } else {
1491 p_msg = p_pdu;
nxpandroidc7611652015-09-23 16:42:05 +05301492 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301493 } else {
1494 /* Get a PDU from link manager or data links */
1495 p_msg = llcp_link_get_next_pdu(false, &next_pdu_length);
nxpandroidc7611652015-09-23 16:42:05 +05301496
nxpandroid8f6d0532017-07-12 18:25:30 +05301497 if (!p_msg) {
1498 return NULL;
1499 }
1500 }
1501
1502 /* Get length of next PDU from link manager or data links without dequeue */
1503 llcp_link_get_next_pdu(true, &next_pdu_length);
1504 while (next_pdu_length > 0) {
1505 /* if it's first visit */
1506 if (!p_agf) {
1507 /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
1508 if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu) {
1509 p_agf = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
1510 if (p_agf) {
1511 p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1512
1513 p = (uint8_t*)(p_agf + 1) + p_agf->offset;
1514
1515 UINT16_TO_BE_STREAM(
1516 p,
1517 LLCP_GET_PDU_HEADER(LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM));
1518 UINT16_TO_BE_STREAM(p, p_msg->len);
1519 memcpy(p, (uint8_t*)(p_msg + 1) + p_msg->offset, p_msg->len);
1520
1521 p_agf->len = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
1522
1523 GKI_freebuf(p_msg);
1524 p_msg = p_agf;
1525 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301526 LOG(ERROR) << StringPrintf("Out of buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301527 return p_msg;
nxpandroidc7611652015-09-23 16:42:05 +05301528 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301529 } else {
1530 break;
1531 }
nxpandroidc7611652015-09-23 16:42:05 +05301532 }
1533
nxpandroid8f6d0532017-07-12 18:25:30 +05301534 /* if next PDU fits into MIU, copy the next PDU into AGF */
1535 if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <=
1536 llcp_cb.lcb.effective_miu) {
1537 /* Get a next PDU from link manager or data links */
1538 p_next_pdu = llcp_link_get_next_pdu(false, &next_pdu_length);
nxpandroidc7611652015-09-23 16:42:05 +05301539
nxf24591c1cbeab2018-02-21 17:32:26 +05301540 p = (uint8_t*)(p_agf + 1) + p_agf->offset + p_agf->len;
nxpandroidc7611652015-09-23 16:42:05 +05301541
nxf24591c1cbeab2018-02-21 17:32:26 +05301542 UINT16_TO_BE_STREAM(p, p_next_pdu->len);
1543 memcpy(p, (uint8_t*)(p_next_pdu + 1) + p_next_pdu->offset,
1544 p_next_pdu->len);
nxpandroidc7611652015-09-23 16:42:05 +05301545
nxf24591c1cbeab2018-02-21 17:32:26 +05301546 p_agf->len += 2 + p_next_pdu->len;
nxpandroidc7611652015-09-23 16:42:05 +05301547
nxf24591c1cbeab2018-02-21 17:32:26 +05301548 GKI_freebuf(p_next_pdu);
1549
1550 /* Get next PDU length from link manager or data links without dequeue */
1551 llcp_link_get_next_pdu(true, &next_pdu_length);
nxpandroid8f6d0532017-07-12 18:25:30 +05301552 } else {
1553 break;
nxpandroidc7611652015-09-23 16:42:05 +05301554 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301555 }
nxpandroidc7611652015-09-23 16:42:05 +05301556
nxpandroid8f6d0532017-07-12 18:25:30 +05301557 if (p_agf)
1558 return p_agf;
1559 else
1560 return p_msg;
nxpandroidc7611652015-09-23 16:42:05 +05301561}
1562
1563/*******************************************************************************
1564**
1565** Function llcp_link_send_to_lower
1566**
1567** Description Send PDU to lower layer
1568**
1569** Returns void
1570**
1571*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301572static void llcp_link_send_to_lower(NFC_HDR* p_pdu) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301573 DispLLCP(p_pdu, false);
nxf24591c1cbeab2018-02-21 17:32:26 +05301574
nxpandroid8f6d0532017-07-12 18:25:30 +05301575 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
nxf24591c1cbeab2018-02-21 17:32:26 +05301576
nxpandroid8f6d0532017-07-12 18:25:30 +05301577 NFC_SendData(NFC_RF_CONN_ID, p_pdu);
nxpandroidc7611652015-09-23 16:42:05 +05301578}
1579
1580/*******************************************************************************
1581**
1582** Function llcp_link_connection_cback
1583**
1584** Description processing incoming data
1585**
1586** Returns void
1587**
1588*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05301589void llcp_link_connection_cback(__attribute__((unused)) uint8_t conn_id,
1590 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301591 if (event == NFC_DATA_CEVT) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301592 DispLLCP((NFC_HDR*)p_data->data.p_data, true);
nxpandroid8f6d0532017-07-12 18:25:30 +05301593 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED) {
1594 /* respoding SYMM while LLCP is deactivated but RF link is not deactivated
1595 * yet */
1596 llcp_link_send_SYMM();
1597 GKI_freebuf((NFC_HDR*)p_data->data.p_data);
1598 } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATION_FAILED) {
1599 /* respoding with invalid LLC PDU until initiator deactivates RF link
1600 *after LLCP activation was failed,
1601 ** so that initiator knows LLCP link activation was failed.
1602 */
1603 llcp_link_send_invalid_pdu();
1604 GKI_freebuf((NFC_HDR*)p_data->data.p_data);
1605 } else {
1606 llcp_cb.lcb.flags |= LLCP_LINK_FLAGS_RX_ANY_LLC_PDU;
1607 llcp_link_proc_rx_data((NFC_HDR*)p_data->data.p_data);
nxpandroidc7611652015-09-23 16:42:05 +05301608 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301609 } else if (event == NFC_ERROR_CEVT) {
1610 /* RF interface specific status code */
1611 llcp_link_deactivate(*(uint8_t*)p_data);
1612 } else if (event == NFC_DEACTIVATE_CEVT) {
1613 if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) &&
1614 (!llcp_cb.lcb.is_initiator)) {
1615 /* peer initiates NFC link deactivation before timeout */
1616 llcp_link_stop_link_timer();
1617 llcp_link_process_link_timeout();
1618 } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATION_FAILED) {
1619 /* do not notify to upper layer because activation failure was already
1620 * notified */
1621 NFC_FlushData(NFC_RF_CONN_ID);
1622 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
1623 } else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED) {
1624 llcp_link_deactivate(LLCP_LINK_RF_LINK_LOSS_ERR);
nxpandroidc7611652015-09-23 16:42:05 +05301625 }
1626
nxpandroid8f6d0532017-07-12 18:25:30 +05301627 NFC_SetStaticRfCback(NULL);
1628 } else if (event == NFC_DATA_START_CEVT) {
1629 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT) {
1630 /* LLCP shall stop LTO timer when receiving the first bit of LLC PDU */
1631 llcp_link_stop_link_timer();
1632 }
1633 }
nxpandroidc7611652015-09-23 16:42:05 +05301634
nxpandroid8f6d0532017-07-12 18:25:30 +05301635 /* LLCP ignores the following events
1636
1637 NFC_CONN_CREATE_CEVT
1638 NFC_CONN_CLOSE_CEVT
1639 */
nxpandroidc7611652015-09-23 16:42:05 +05301640}
1641
nxpandroidc7611652015-09-23 16:42:05 +05301642/*******************************************************************************
1643**
1644** Function llcp_pdu_type
1645**
1646** Description
1647**
1648** Returns string of PDU type
1649**
1650*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05301651static std::string llcp_pdu_type(uint8_t ptype) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301652 switch (ptype) {
nxpandroidc7611652015-09-23 16:42:05 +05301653 case LLCP_PDU_SYMM_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301654 return "SYMM";
nxpandroidc7611652015-09-23 16:42:05 +05301655 case LLCP_PDU_PAX_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301656 return "PAX";
nxpandroidc7611652015-09-23 16:42:05 +05301657 case LLCP_PDU_AGF_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301658 return "AGF";
nxpandroidc7611652015-09-23 16:42:05 +05301659 case LLCP_PDU_UI_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301660 return "UI";
nxpandroidc7611652015-09-23 16:42:05 +05301661 case LLCP_PDU_CONNECT_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301662 return "CONNECT";
nxpandroidc7611652015-09-23 16:42:05 +05301663 case LLCP_PDU_DISC_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301664 return "DISC";
nxpandroidc7611652015-09-23 16:42:05 +05301665 case LLCP_PDU_CC_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301666 return "CC";
nxpandroidc7611652015-09-23 16:42:05 +05301667 case LLCP_PDU_DM_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301668 return "DM";
nxpandroidc7611652015-09-23 16:42:05 +05301669 case LLCP_PDU_FRMR_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301670 return "FRMR";
nxpandroidc7611652015-09-23 16:42:05 +05301671 case LLCP_PDU_SNL_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301672 return "SNL";
nxpandroidc7611652015-09-23 16:42:05 +05301673 case LLCP_PDU_I_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301674 return "I";
nxpandroidc7611652015-09-23 16:42:05 +05301675 case LLCP_PDU_RR_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301676 return "RR";
nxpandroidc7611652015-09-23 16:42:05 +05301677 case LLCP_PDU_RNR_TYPE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301678 return "RNR";
nxpandroidc7611652015-09-23 16:42:05 +05301679 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05301680 return "RESERVED";
1681 }
nxpandroidc7611652015-09-23 16:42:05 +05301682}