1 /******************************************************************************
2 *
3 * Copyright (C) 2010-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the LLCP Link Management
22 *
23 ******************************************************************************/
24
25 #include <string.h>
26 #include "gki.h"
27 #include "nfc_target.h"
28 #include "bt_types.h"
29 #include "trace_api.h"
30 #include "llcp_int.h"
31 #include "llcp_defs.h"
32 #include "nfc_int.h"
33
34 const UINT16 llcp_link_rwt[15] = /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */
35 {
36 1, /* WT=0, 302us */
37 1, /* WT=1, 604us */
38 2, /* WT=2, 1208us */
39 3, /* WT=3, 2.4ms */
40 5, /* WT=4, 4.8ms */
41 10, /* WT=5, 9.7ms */
42 20, /* WT=6, 19.3ms */
43 39, /* WT=7, 38.7ms */
44 78, /* WT=8, 77.3ms */
45 155, /* WT=9, 154.6ms */
46 310, /* WT=10, 309.2ms */
47 619, /* WT=11, 618.5ms */
48 1237, /* WT=12, 1237.0ms */
49 2474, /* WT=13, 2474.0ms */
50 4948, /* WT=14, 4948.0ms */
51 };
52
53 static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes);
54 static BOOLEAN llcp_link_version_agreement (void);
55
56 static void llcp_link_send_SYMM (void);
57 static void llcp_link_update_status (BOOLEAN is_activated);
58 static void llcp_link_check_congestion (void);
59 static void llcp_link_check_uncongested (void);
60 static void llcp_link_proc_ui_pdu (UINT8 local_sap, UINT8 remote_sap, UINT16 ui_pdu_length, UINT8 *p_ui_pdu, BT_HDR *p_msg);
61 static void llcp_link_proc_agf_pdu (BT_HDR *p_msg);
62 static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg);
63 static void llcp_link_proc_rx_data (BT_HDR *p_msg);
64
65 static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length);
66 static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_agf);
67 static void llcp_link_send_to_lower (BT_HDR *p_msg);
68
69 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
70 extern tLLCP_TEST_PARAMS llcp_test_params;
71 #endif
72
73 /* debug functions type */
74 #if (BT_TRACE_VERBOSE == TRUE)
75 static char *llcp_pdu_type (UINT8 ptype);
76 #endif
77
78 /*******************************************************************************
79 **
80 ** Function llcp_link_start_inactivity_timer
81 **
82 ** Description This function start LLCP link inactivity timer.
83 **
84 ** Returns void
85 **
86 *******************************************************************************/
llcp_link_start_inactivity_timer(void)87 static void llcp_link_start_inactivity_timer (void)
88 {
89 if ( (llcp_cb.lcb.inact_timer.in_use == FALSE)
90 &&(llcp_cb.lcb.inact_timeout > 0) )
91 {
92 LLCP_TRACE_DEBUG1 ("Start inactivity_timer: %d ms", llcp_cb.lcb.inact_timeout);
93
94 nfc_start_quick_timer (&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT,
95 ((UINT32) llcp_cb.lcb.inact_timeout) * QUICK_TIMER_TICKS_PER_SEC / 1000);
96 }
97 }
98
99 /*******************************************************************************
100 **
101 ** Function llcp_link_stop_inactivity_timer
102 **
103 ** Description This function stop LLCP link inactivity timer.
104 **
105 ** Returns void
106 **
107 *******************************************************************************/
llcp_link_stop_inactivity_timer(void)108 static void llcp_link_stop_inactivity_timer (void)
109 {
110 if (llcp_cb.lcb.inact_timer.in_use)
111 {
112 LLCP_TRACE_DEBUG0 ("Stop inactivity_timer");
113
114 nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer);
115 }
116 }
117
118 /*******************************************************************************
119 **
120 ** Function llcp_link_start_link_timer
121 **
122 ** Description This function starts LLCP link timer (LTO or delay response).
123 **
124 ** Returns void
125 **
126 *******************************************************************************/
llcp_link_start_link_timer(void)127 static void llcp_link_start_link_timer (void)
128 {
129 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
130 {
131 /* wait for application layer sending data */
132 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
133 (((UINT32) llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
134 }
135 else
136 {
137 /* wait for data to receive from remote */
138 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
139 ((UINT32) llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000);
140 }
141 }
142
143 /*******************************************************************************
144 **
145 ** Function llcp_link_stop_link_timer
146 **
147 ** Description This function stop LLCP link timer (LTO or delay response).
148 **
149 ** Returns void
150 **
151 *******************************************************************************/
llcp_link_stop_link_timer(void)152 static void llcp_link_stop_link_timer (void)
153 {
154 nfc_stop_quick_timer (&llcp_cb.lcb.timer);
155 }
156
157 /*******************************************************************************
158 **
159 ** Function llcp_link_activate
160 **
161 ** Description Activate LLCP link
162 **
163 ** Returns tLLCP_STATUS
164 **
165 *******************************************************************************/
llcp_link_activate(tLLCP_ACTIVATE_CONFIG * p_config)166 tLLCP_STATUS llcp_link_activate (tLLCP_ACTIVATE_CONFIG *p_config)
167 {
168 LLCP_TRACE_DEBUG0 ("llcp_link_activate ()");
169
170 /* At this point, MAC link activation procedure has been successfully completed */
171
172 /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */
173 if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE)
174 {
175 LLCP_TRACE_WARNING2 ("llcp_link_activate (): max payload size (%d) must be %d bytes",
176 p_config->max_payload_size, LLCP_NCI_MAX_PAYL_SIZE);
177 }
178
179 /* Processing the parametes that have been received with the MAC link activation */
180 if (llcp_link_parse_gen_bytes (p_config->gen_bytes_len,
181 p_config->p_gen_bytes ) == FALSE)
182 {
183 LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to parse general bytes");
184 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_BAD_GEN_BYTES);
185 return LLCP_STATUS_FAIL;
186 }
187
188 /*
189 ** For the Target device, the scaled value of RWT MUST be less than or equal to the
190 ** scaled value of the LLC Link Timeout (LTO).
191 */
192 if ((p_config->is_initiator) && (llcp_link_rwt[p_config->waiting_time] > llcp_cb.lcb.peer_lto))
193 {
194 LLCP_TRACE_WARNING3 ("llcp_link_activate (): WT (%d, %dms) must be less than or equal to LTO (%dms)",
195 p_config->waiting_time,
196 llcp_link_rwt[p_config->waiting_time],
197 llcp_cb.lcb.peer_lto);
198 }
199
200 /* extend LTO as much as internally required processing time and propagation delays */
201 llcp_cb.lcb.peer_lto += LLCP_INTERNAL_TX_DELAY + LLCP_INTERNAL_RX_DELAY;
202
203 /* LLCP version number agreement */
204 if (llcp_link_version_agreement () == FALSE)
205 {
206 LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to agree version");
207 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_VERSION_FAILED);
208 return LLCP_STATUS_FAIL;
209 }
210
211 llcp_cb.lcb.is_initiator = p_config->is_initiator;
212
213 /* set tx MIU to MIN (MIU of local LLCP, MIU of peer LLCP) */
214
215 if (llcp_cb.lcb.local_link_miu >= llcp_cb.lcb.peer_miu)
216 llcp_cb.lcb.effective_miu = llcp_cb.lcb.peer_miu;
217 else
218 llcp_cb.lcb.effective_miu = llcp_cb.lcb.local_link_miu;
219
220 /*
221 ** When entering the normal operation phase, LLCP shall initialize the symmetry
222 ** procedure.
223 */
224 if (llcp_cb.lcb.is_initiator)
225 {
226 LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Initiator");
227
228 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_init;
229 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
230
231 if (llcp_cb.lcb.delay_first_pdu_timeout > 0)
232 {
233 /* give a chance to upper layer to send PDU if need */
234 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_DELAY_FIRST_PDU,
235 (((UINT32) llcp_cb.lcb.delay_first_pdu_timeout) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
236 }
237 else
238 {
239 llcp_link_send_SYMM ();
240 }
241 }
242 else
243 {
244 LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Target");
245 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target;
246 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
247
248 /* wait for data to receive from remote */
249 llcp_link_start_link_timer ();
250 }
251
252
253 /*
254 ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set data callback
255 ** because LLCP PDU could be in NCI queue.
256 */
257 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
258
259 /* LLCP Link Activation completed */
260 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_COMPLETE_EVT, LLCP_LINK_SUCCESS);
261
262 /* Update link status to service layer */
263 llcp_link_update_status (TRUE);
264
265 NFC_SetStaticRfCback (llcp_link_connection_cback);
266
267 return (LLCP_STATUS_SUCCESS);
268 }
269
270 /*******************************************************************************
271 **
272 ** Function llcp_deactivate_cleanup
273 **
274 ** Description Clean up for link deactivation
275 **
276 ** Returns void
277 **
278 *******************************************************************************/
llcp_deactivate_cleanup(UINT8 reason)279 static void llcp_deactivate_cleanup (UINT8 reason)
280 {
281 /* report SDP failure for any pending request */
282 llcp_sdp_proc_deactivation ();
283
284 /* Update link status to service layer */
285 llcp_link_update_status (FALSE);
286
287 /* We had sent out DISC */
288 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
289
290 llcp_link_stop_link_timer ();
291
292 /* stop inactivity timer */
293 llcp_link_stop_inactivity_timer ();
294
295 /* Let upper layer deactivate local link */
296 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_DEACTIVATED_EVT, reason);
297 }
298
299 /*******************************************************************************
300 **
301 ** Function llcp_link_process_link_timeout
302 **
303 ** Description Process timeout events for LTO, SYMM and deactivating
304 **
305 ** Returns void
306 **
307 *******************************************************************************/
llcp_link_process_link_timeout(void)308 void llcp_link_process_link_timeout (void)
309 {
310 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
311 {
312 if ((llcp_cb.lcb.symm_delay > 0) && (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT))
313 {
314 /* upper layer doesn't have anything to send */
315 LLCP_TRACE_DEBUG0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
316 llcp_link_send_SYMM ();
317
318 /* wait for data to receive from remote */
319 llcp_link_start_link_timer ();
320
321 /* start inactivity timer */
322 if (llcp_cb.num_data_link_connection == 0)
323 {
324 llcp_link_start_inactivity_timer ();
325 }
326 }
327 else
328 {
329 LLCP_TRACE_ERROR0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_REMOTE_XMIT_NEXT");
330 llcp_link_deactivate (LLCP_LINK_TIMEOUT);
331 }
332 }
333 else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
334 {
335 llcp_deactivate_cleanup (llcp_cb.lcb.link_deact_reason);
336
337 NFC_SetStaticRfCback (NULL);
338 }
339 }
340
341 /*******************************************************************************
342 **
343 ** Function llcp_link_deactivate
344 **
345 ** Description Deactivate LLCP link
346 **
347 ** Returns void
348 **
349 *******************************************************************************/
llcp_link_deactivate(UINT8 reason)350 void llcp_link_deactivate (UINT8 reason)
351 {
352 UINT8 local_sap, idx;
353 tLLCP_DLCB *p_dlcb;
354 tLLCP_APP_CB *p_app_cb;
355
356 LLCP_TRACE_DEBUG1 ("llcp_link_deactivate () reason = 0x%x", reason);
357
358 /* Release any held buffers in signaling PDU queue */
359 while (llcp_cb.lcb.sig_xmit_q.p_first)
360 GKI_freebuf (GKI_dequeue (&llcp_cb.lcb.sig_xmit_q));
361
362 /* Release any held buffers in UI PDU queue */
363 for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++)
364 {
365 p_app_cb = llcp_util_get_app_cb (local_sap);
366
367 if ( (p_app_cb)
368 &&(p_app_cb->p_app_cback) )
369 {
370 while (p_app_cb->ui_xmit_q.p_first)
371 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
372
373 p_app_cb->is_ui_tx_congested = FALSE;
374
375 while (p_app_cb->ui_rx_q.p_first)
376 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
377 }
378 }
379
380 llcp_cb.total_tx_ui_pdu = 0;
381 llcp_cb.total_rx_ui_pdu = 0;
382
383 /* Notify all of data link */
384 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
385 {
386 if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
387 {
388 p_dlcb = &(llcp_cb.dlcb[idx]);
389
390 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, NULL);
391 }
392 }
393 llcp_cb.total_tx_i_pdu = 0;
394 llcp_cb.total_rx_i_pdu = 0;
395
396 llcp_cb.overall_tx_congested = FALSE;
397 llcp_cb.overall_rx_congested = FALSE;
398
399 if ( (reason == LLCP_LINK_FRAME_ERROR)
400 ||(reason == LLCP_LINK_LOCAL_INITIATED) )
401 {
402 /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP */
403 NFC_FlushData (NFC_RF_CONN_ID);
404
405 llcp_util_send_disc (LLCP_SAP_LM, LLCP_SAP_LM);
406
407 /* Wait until DISC is sent to peer */
408 LLCP_TRACE_DEBUG0 ("llcp_link_deactivate (): Wait until DISC is sent to peer");
409
410 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING;
411
412 if (llcp_cb.lcb.sig_xmit_q.count == 0)
413 {
414 /* if DISC is sent to NFCC, wait for short period for NFCC to send it to peer */
415 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
416 ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
417 }
418
419 llcp_cb.lcb.link_deact_reason = reason;
420 return;
421 }
422 else if ( (reason == LLCP_LINK_REMOTE_INITIATED)
423 &&(!llcp_cb.lcb.is_initiator) )
424 {
425 /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */
426 llcp_link_send_SYMM ();
427 }
428 else /* for link timeout and interface error */
429 {
430 NFC_FlushData (NFC_RF_CONN_ID);
431 }
432
433 llcp_deactivate_cleanup (reason);
434 }
435
436 /*******************************************************************************
437 **
438 ** Function llcp_link_parse_gen_bytes
439 **
440 ** Description Check LLCP magic number and get parameters in general bytes
441 **
442 ** Returns TRUE if success
443 **
444 *******************************************************************************/
llcp_link_parse_gen_bytes(UINT8 gen_bytes_len,UINT8 * p_gen_bytes)445 static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes)
446 {
447 UINT8 *p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN;
448 UINT8 length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN;
449
450 if ( (gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN)
451 &&(*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0)
452 &&(*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1)
453 &&(*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2) )
454 {
455 /* in case peer didn't include these */
456 llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU;
457 llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS;
458
459 return (llcp_util_parse_link_params (length, p));
460 }
461 else /* if this is not LLCP */
462 {
463 return (FALSE);
464 }
465
466 return (TRUE);
467 }
468
469 /*******************************************************************************
470 **
471 ** Function llcp_link_version_agreement
472 **
473 ** Description LLCP version number agreement
474 **
475 ** Returns TRUE if success
476 **
477 *******************************************************************************/
llcp_link_version_agreement(void)478 static BOOLEAN llcp_link_version_agreement (void)
479 {
480 UINT8 peer_major_version, peer_minor_version;
481
482 peer_major_version = LLCP_GET_MAJOR_VERSION (llcp_cb.lcb.peer_version);
483 peer_minor_version = LLCP_GET_MINOR_VERSION (llcp_cb.lcb.peer_version);
484
485 if (peer_major_version < LLCP_MIN_MAJOR_VERSION)
486 {
487 LLCP_TRACE_ERROR1("llcp_link_version_agreement(): unsupported peer version number. Peer Major Version:%d", peer_major_version);
488 return FALSE;
489 }
490 else
491 {
492 if (peer_major_version == LLCP_VERSION_MAJOR)
493 {
494 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
495 if (peer_minor_version >= LLCP_VERSION_MINOR)
496 {
497 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
498 }
499 else
500 {
501 llcp_cb.lcb.agreed_minor_version = peer_minor_version;
502 }
503 }
504 else if (peer_major_version < LLCP_VERSION_MAJOR)
505 {
506 /* so far we can support backward compatibility */
507 llcp_cb.lcb.agreed_major_version = peer_major_version;
508 llcp_cb.lcb.agreed_minor_version = peer_minor_version;
509 }
510 else
511 {
512 /* let peer (higher major version) decide it */
513 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
514 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
515 }
516
517 LLCP_TRACE_DEBUG6 ("local version:%d.%d, remote version:%d.%d, agreed version:%d.%d",
518 LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR,
519 peer_major_version, peer_minor_version,
520 llcp_cb.lcb.agreed_major_version, llcp_cb.lcb.agreed_minor_version);
521
522 return (TRUE);
523 }
524 }
525
526 /*******************************************************************************
527 **
528 ** Function llcp_link_update_status
529 **
530 ** Description Notify all of service layer client link status change
531 **
532 ** Returns void
533 **
534 *******************************************************************************/
llcp_link_update_status(BOOLEAN is_activated)535 static void llcp_link_update_status (BOOLEAN is_activated)
536 {
537 tLLCP_SAP_CBACK_DATA data;
538 tLLCP_APP_CB *p_app_cb;
539 UINT8 sap;
540
541 data.link_status.event = LLCP_SAP_EVT_LINK_STATUS;
542 data.link_status.is_activated = is_activated;
543 data.link_status.is_initiator = llcp_cb.lcb.is_initiator;
544
545 /* notify all SAP so they can create connection while link is activated */
546 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
547 {
548 p_app_cb = llcp_util_get_app_cb (sap);
549
550 if ( (p_app_cb)
551 &&(p_app_cb->p_app_cback) )
552 {
553 data.link_status.local_sap = sap;
554 p_app_cb->p_app_cback (&data);
555 }
556 }
557 }
558
559 /*******************************************************************************
560 **
561 ** Function llcp_link_check_congestion
562 **
563 ** Description Check overall congestion status
564 ** Notify to all of upper layer if congested
565 **
566 ** Returns void
567 **
568 *******************************************************************************/
llcp_link_check_congestion(void)569 static void llcp_link_check_congestion (void)
570 {
571 tLLCP_SAP_CBACK_DATA data;
572 tLLCP_APP_CB *p_app_cb;
573 UINT8 sap, idx;
574
575 if (llcp_cb.overall_tx_congested)
576 {
577 /* already congested so no need to check again */
578 return;
579 }
580
581 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)
582 {
583 /* overall buffer usage is high */
584 llcp_cb.overall_tx_congested = TRUE;
585
586 LLCP_TRACE_WARNING2 ("overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
587 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
588
589 data.congest.event = LLCP_SAP_EVT_CONGEST;
590 data.congest.is_congested = TRUE;
591
592 /* notify logical data link congestion status */
593 data.congest.remote_sap = LLCP_INVALID_SAP;
594 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
595
596 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
597 {
598 p_app_cb = llcp_util_get_app_cb (sap);
599
600 if ( (p_app_cb)
601 &&(p_app_cb->p_app_cback)
602 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) )
603 {
604 /* if already congested then no need to notify again */
605 if (!p_app_cb->is_ui_tx_congested)
606 {
607 p_app_cb->is_ui_tx_congested = TRUE;
608
609 LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congestion start: count=%d",
610 sap, p_app_cb->ui_xmit_q.count);
611
612 data.congest.local_sap = sap;
613 p_app_cb->p_app_cback (&data);
614 }
615 }
616 }
617
618 /* notify data link connection congestion status */
619 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
620
621 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++ )
622 {
623 if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
624 &&(llcp_cb.dlcb[idx].remote_busy == FALSE)
625 &&(llcp_cb.dlcb[idx].is_tx_congested == FALSE) )
626 {
627 llcp_cb.dlcb[idx].is_tx_congested = TRUE;
628
629 LLCP_TRACE_WARNING3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d",
630 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
631 llcp_cb.dlcb[idx].i_xmit_q.count);
632
633 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
634 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
635
636 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
637 }
638 }
639 }
640 }
641
642 /*******************************************************************************
643 **
644 ** Function llcp_link_check_uncongested
645 **
646 ** Description Check overall congestion status, logical data link and
647 ** data link connection congestion status
648 ** Notify to each upper layer if uncongested
649 **
650 ** Returns void
651 **
652 *******************************************************************************/
llcp_link_check_uncongested(void)653 static void llcp_link_check_uncongested (void)
654 {
655 tLLCP_SAP_CBACK_DATA data;
656 tLLCP_APP_CB *p_app_cb;
657 UINT8 xx, sap, idx;
658
659 if (llcp_cb.overall_tx_congested)
660 {
661 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <= llcp_cb.max_num_tx_buff / 2)
662 {
663 /* overall congestion is cleared */
664 llcp_cb.overall_tx_congested = FALSE;
665
666 LLCP_TRACE_WARNING2 ("overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
667 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
668 }
669 else
670 {
671 /* wait until more data packets are sent out */
672 return;
673 }
674 }
675
676 data.congest.event = LLCP_SAP_EVT_CONGEST;
677 data.congest.is_congested = FALSE;
678
679 /* if total number of UI PDU is below threshold */
680 if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff)
681 {
682 /* check and notify logical data link congestion status */
683 data.congest.remote_sap = LLCP_INVALID_SAP;
684 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
685
686 /*
687 ** start point of uncongested status notification is in round robin
688 ** so each logical data link has equal chance of transmitting.
689 */
690 sap = llcp_cb.ll_tx_uncongest_ntf_start_sap;
691
692 for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++)
693 {
694 /* no logical data link on LM and SDP */
695 if (sap > LLCP_SAP_SDP)
696 {
697 p_app_cb = llcp_util_get_app_cb (sap);
698
699 if ( (p_app_cb)
700 &&(p_app_cb->p_app_cback)
701 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
702 &&(p_app_cb->is_ui_tx_congested)
703 &&(p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end) )
704 {
705 /* if it was congested but now tx queue count is below threshold */
706 p_app_cb->is_ui_tx_congested = FALSE;
707
708 LLCP_TRACE_DEBUG2 ("Logical link (SAP=0x%X) congestion end: count=%d",
709 sap, p_app_cb->ui_xmit_q.count);
710
711 data.congest.local_sap = sap;
712 p_app_cb->p_app_cback (&data);
713 }
714 }
715
716 sap = (sap + 1) % LLCP_NUM_SAPS;
717 }
718
719 /* move start point for next logical data link */
720 for (xx = 0; xx < LLCP_NUM_SAPS; xx++)
721 {
722 sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS;
723
724 if (sap > LLCP_SAP_SDP)
725 {
726 p_app_cb = llcp_util_get_app_cb (sap);
727
728 if ( (p_app_cb)
729 &&(p_app_cb->p_app_cback)
730 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) )
731 {
732 llcp_cb.ll_tx_uncongest_ntf_start_sap = sap;
733 break;
734 }
735 }
736 }
737 }
738
739 /* notify data link connection congestion status */
740 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
741
742 /*
743 ** start point of uncongested status notification is in round robin
744 ** so each data link connection has equal chance of transmitting.
745 */
746 idx = llcp_cb.dl_tx_uncongest_ntf_start_idx;
747
748 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
749 {
750 /* if it was congested but now tx queue is below threshold (receiving window) */
751 if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
752 &&(llcp_cb.dlcb[idx].is_tx_congested)
753 &&(llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2) )
754 {
755 llcp_cb.dlcb[idx].is_tx_congested = FALSE;
756
757 if (llcp_cb.dlcb[idx].remote_busy == FALSE)
758 {
759 LLCP_TRACE_DEBUG3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d",
760 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
761 llcp_cb.dlcb[idx].i_xmit_q.count);
762
763 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
764 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
765
766 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
767 }
768 }
769 idx = (idx + 1) % LLCP_MAX_DATA_LINK;
770 }
771
772 /* move start point for next data link connection */
773 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
774 {
775 idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK;
776 if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
777 {
778 llcp_cb.dl_tx_uncongest_ntf_start_idx = idx;
779 break;
780 }
781 }
782 }
783
784 /*******************************************************************************
785 **
786 ** Function llcp_link_send_SYMM
787 **
788 ** Description Send SYMM PDU
789 **
790 ** Returns void
791 **
792 *******************************************************************************/
llcp_link_send_SYMM(void)793 static void llcp_link_send_SYMM (void)
794 {
795 BT_HDR *p_msg;
796 UINT8 *p;
797
798 p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
799
800 if (p_msg)
801 {
802 p_msg->len = LLCP_PDU_SYMM_SIZE;
803 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
804
805 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
806 UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM ));
807
808 llcp_link_send_to_lower (p_msg);
809 }
810 }
811
812 /*******************************************************************************
813 **
814 ** Function llcp_link_check_send_data
815 **
816 ** Description Send PDU to peer
817 **
818 ** Returns void
819 **
820 *******************************************************************************/
llcp_link_check_send_data(void)821 void llcp_link_check_send_data (void)
822 {
823 BT_HDR *p_pdu;
824
825 /* don't re-enter while processing to prevent out of sequence */
826 if (llcp_cb.lcb.is_sending_data)
827 return;
828 else
829 llcp_cb.lcb.is_sending_data = TRUE;
830
831 /*
832 ** check overall congestion due to high usage of buffer pool
833 ** if congested then notify all of upper layers not to send any more data
834 */
835 llcp_link_check_congestion ();
836
837 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
838 {
839 LLCP_TRACE_DEBUG0 ("llcp_link_check_send_data () in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
840
841 p_pdu = llcp_link_build_next_pdu (NULL);
842
843 /*
844 ** For data link connection,
845 ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in this transmission.
846 ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's not congested,
847 ** then RR PDU will be sent.
848 ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's congested,
849 ** then RNR PDU will be sent.
850 ** If local busy state has been changed then RR or RNR PDU may be sent.
851 */
852 llcp_dlc_check_to_send_rr_rnr ();
853
854 /* add RR/RNR PDU to be sent if any */
855 p_pdu = llcp_link_build_next_pdu (p_pdu);
856
857 if (p_pdu != NULL)
858 {
859 llcp_link_send_to_lower (p_pdu);
860
861 /* stop inactivity timer */
862 llcp_link_stop_inactivity_timer ();
863
864 /* check congestion status after sending out some data */
865 llcp_link_check_uncongested ();
866 }
867 else
868 {
869 /* There is no data to send, so send SYMM */
870 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
871 {
872 if (llcp_cb.lcb.symm_delay > 0)
873 {
874 /* wait for application layer sending data */
875 llcp_link_start_link_timer ();
876 llcp_cb.lcb.is_sending_data = FALSE;
877 return;
878 }
879 else
880 {
881 llcp_link_send_SYMM ();
882
883 /* start inactivity timer */
884 if (llcp_cb.num_data_link_connection == 0)
885 {
886 llcp_link_start_inactivity_timer ();
887 }
888 }
889 }
890 else
891 {
892 llcp_cb.lcb.is_sending_data = FALSE;
893 return;
894 }
895 }
896
897 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
898 {
899 /* wait for short period for NFCC to send DISC */
900 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
901 ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
902 }
903 else
904 {
905 /* wait for data to receive from remote */
906 llcp_link_start_link_timer ();
907 }
908 }
909
910 llcp_cb.lcb.is_sending_data = FALSE;
911 }
912
913 /*******************************************************************************
914 **
915 ** Function llcp_link_proc_ui_pdu
916 **
917 ** Description Process UI PDU from peer device
918 **
919 ** Returns None
920 **
921 *******************************************************************************/
llcp_link_proc_ui_pdu(UINT8 local_sap,UINT8 remote_sap,UINT16 ui_pdu_length,UINT8 * p_ui_pdu,BT_HDR * p_msg)922 static void llcp_link_proc_ui_pdu (UINT8 local_sap,
923 UINT8 remote_sap,
924 UINT16 ui_pdu_length,
925 UINT8 *p_ui_pdu,
926 BT_HDR *p_msg)
927 {
928 BOOLEAN appended;
929 BT_HDR *p_last_buf;
930 UINT16 available_bytes;
931 UINT8 *p_dst;
932 tLLCP_APP_CB *p_app_cb;
933 tLLCP_SAP_CBACK_DATA data;
934 tLLCP_DLCB *p_dlcb;
935
936 p_app_cb = llcp_util_get_app_cb (local_sap);
937 /*if UI PDU sent to SAP with data link connection*/
938 if ((p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap)))
939 {
940 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0);
941 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
942 if (p_msg)
943 {
944 GKI_freebuf (p_msg);
945 }
946 return;
947 }
948
949 /* if application is registered and expecting UI PDU on logical data link */
950 if ( (p_app_cb)
951 &&(p_app_cb->p_app_cback)
952 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) )
953 {
954 LLCP_TRACE_DEBUG2 ("llcp_link_proc_ui_pdu () Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
955
956 /* if this is not from AGF PDU */
957 if (p_msg)
958 {
959 ui_pdu_length = p_msg->len; /* including LLCP header */
960 p_ui_pdu = (UINT8*) (p_msg + 1) + p_msg->offset;
961 }
962
963 appended = FALSE;
964
965 /* get last buffer in rx queue */
966 p_last_buf = (BT_HDR *) GKI_getlast (&p_app_cb->ui_rx_q);
967
968 if (p_last_buf)
969 {
970 /* get max length to append at the end of buffer */
971 available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
972
973 /* if new UI PDU with length can be attached at the end of buffer */
974 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length)
975 {
976 p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
977
978 /* add length of UI PDU */
979 UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
980
981 /* copy UI PDU with LLCP header */
982 memcpy (p_dst, p_ui_pdu, ui_pdu_length);
983
984 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
985
986 if (p_msg)
987 GKI_freebuf (p_msg);
988
989 appended = TRUE;
990 }
991 }
992
993 /* if it is not available to append */
994 if (!appended)
995 {
996 /* if it's not from AGF PDU */
997 if (p_msg)
998 {
999 /* add length of PDU in front of UI PDU (reuse room for NCI header) */
1000 p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE;
1001 UINT16_TO_BE_STREAM (p_ui_pdu, ui_pdu_length);
1002
1003 p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE;
1004 p_msg->len += LLCP_PDU_AGF_LEN_SIZE;
1005 p_msg->layer_specific = 0;
1006 }
1007 else
1008 {
1009 p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
1010
1011 if (p_msg)
1012 {
1013 p_dst = (UINT8*) (p_msg + 1);
1014
1015 /* add length of PDU in front of UI PDU */
1016 UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
1017
1018 memcpy (p_dst, p_ui_pdu, ui_pdu_length);
1019
1020 p_msg->offset = 0;
1021 p_msg->len = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
1022 p_msg->layer_specific = 0;
1023 }
1024 else
1025 {
1026 LLCP_TRACE_ERROR0 ("llcp_link_proc_ui_pdu (): out of buffer");
1027 }
1028 }
1029
1030 /* insert UI PDU in rx queue */
1031 if (p_msg)
1032 {
1033 GKI_enqueue (&p_app_cb->ui_rx_q, p_msg);
1034 llcp_cb.total_rx_ui_pdu++;
1035 }
1036 }
1037
1038 if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start)
1039 {
1040 LLCP_TRACE_WARNING2 ("llcp_link_proc_ui_pdu (): SAP:0x%x, rx link is congested (%d), discard oldest UI PDU",
1041 local_sap, p_app_cb->ui_rx_q.count);
1042
1043 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
1044 llcp_cb.total_rx_ui_pdu--;
1045 }
1046
1047 if ((p_app_cb->ui_rx_q.count == 1) && (appended == FALSE))
1048 {
1049 data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
1050 data.data_ind.local_sap = local_sap;
1051 data.data_ind.remote_sap = remote_sap;
1052 data.data_ind.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
1053 (*p_app_cb->p_app_cback) (&data);
1054 }
1055 }
1056 else
1057 {
1058 LLCP_TRACE_ERROR1 ("llcp_link_proc_ui_pdu (): Unregistered SAP:0x%x", local_sap);
1059
1060 if (p_msg)
1061 {
1062 GKI_freebuf (p_msg);
1063 }
1064 }
1065 }
1066
1067 /*******************************************************************************
1068 **
1069 ** Function llcp_link_proc_agf_pdu
1070 **
1071 ** Description Process AGF PDU from peer device
1072 **
1073 ** Returns void
1074 **
1075 *******************************************************************************/
llcp_link_proc_agf_pdu(BT_HDR * p_agf)1076 static void llcp_link_proc_agf_pdu (BT_HDR *p_agf)
1077 {
1078 UINT16 agf_length;
1079 UINT8 *p, *p_info, *p_pdu_length;
1080 UINT16 pdu_hdr, pdu_length;
1081 UINT8 dsap, ptype, ssap;
1082
1083 p_agf->len -= LLCP_PDU_HEADER_SIZE;
1084 p_agf->offset += LLCP_PDU_HEADER_SIZE;
1085
1086 /*
1087 ** check integrity of AGF PDU and get number of PDUs in AGF PDU
1088 */
1089 agf_length = p_agf->len;
1090 p = (UINT8 *) (p_agf + 1) + p_agf->offset;
1091
1092 while (agf_length > 0)
1093 {
1094 if (agf_length > LLCP_PDU_AGF_LEN_SIZE)
1095 {
1096 BE_STREAM_TO_UINT16 (pdu_length, p);
1097 agf_length -= LLCP_PDU_AGF_LEN_SIZE;
1098 }
1099 else
1100 {
1101 break;
1102 }
1103
1104 if (pdu_length <= agf_length)
1105 {
1106 p += pdu_length;
1107 agf_length -= pdu_length;
1108 }
1109 else
1110 {
1111 break;
1112 }
1113 }
1114
1115 if (agf_length != 0)
1116 {
1117 LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): Received invalid AGF PDU");
1118 GKI_freebuf (p_agf);
1119 return;
1120 }
1121
1122 /*
1123 ** Process PDUs in AGF
1124 */
1125 agf_length = p_agf->len;
1126 p = (UINT8 *) (p_agf + 1) + p_agf->offset;
1127
1128 while (agf_length > 0)
1129 {
1130 /* get length of PDU */
1131 p_pdu_length = p;
1132 BE_STREAM_TO_UINT16 (pdu_length, p);
1133 agf_length -= LLCP_PDU_AGF_LEN_SIZE;
1134
1135 /* get DSAP/PTYPE/SSAP */
1136 p_info = p;
1137 BE_STREAM_TO_UINT16 (pdu_hdr, p_info );
1138
1139 dsap = LLCP_GET_DSAP (pdu_hdr);
1140 ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
1141 ssap = LLCP_GET_SSAP (pdu_hdr);
1142
1143 #if (BT_TRACE_VERBOSE == TRUE)
1144 LLCP_TRACE_DEBUG4 ("llcp_link_proc_agf_pdu (): Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x in AGF",
1145 dsap, llcp_pdu_type (ptype), ptype, ssap);
1146 #endif
1147
1148 if ( (ptype == LLCP_PDU_DISC_TYPE)
1149 &&(dsap == LLCP_SAP_LM)
1150 &&(ssap == LLCP_SAP_LM) )
1151 {
1152 GKI_freebuf (p_agf);
1153 llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
1154 return;
1155 }
1156 else if (ptype == LLCP_PDU_SYMM_TYPE)
1157 {
1158 LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): SYMM PDU exchange shall not be in AGF");
1159 }
1160 else if (ptype == LLCP_PDU_PAX_TYPE)
1161 {
1162 LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): PAX PDU exchange shall not be used");
1163 }
1164 else if (ptype == LLCP_PDU_SNL_TYPE)
1165 {
1166 llcp_sdp_proc_snl ((UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
1167 }
1168 else if ((ptype == LLCP_PDU_UI_TYPE) && (pdu_length > LLCP_PDU_HEADER_SIZE))
1169 {
1170 llcp_link_proc_ui_pdu (dsap, ssap, pdu_length, p, NULL);
1171 }
1172 else if (ptype == LLCP_PDU_I_TYPE)
1173 {
1174 llcp_dlc_proc_i_pdu (dsap, ssap, pdu_length, p, NULL);
1175 }
1176 else /* let data link connection handle PDU */
1177 {
1178 llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
1179 }
1180
1181 p += pdu_length;
1182 agf_length -= pdu_length;
1183 }
1184
1185 GKI_freebuf (p_agf);
1186 }
1187
1188 /*******************************************************************************
1189 **
1190 ** Function llcp_link_proc_rx_pdu
1191 **
1192 ** Description Process received PDU from peer device
1193 **
1194 ** Returns void
1195 **
1196 *******************************************************************************/
llcp_link_proc_rx_pdu(UINT8 dsap,UINT8 ptype,UINT8 ssap,BT_HDR * p_msg)1197 static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg)
1198 {
1199 BOOLEAN free_buffer = TRUE;
1200 UINT8 *p_data;
1201
1202 switch (ptype)
1203 {
1204 case LLCP_PDU_PAX_TYPE:
1205 LLCP_TRACE_ERROR0 ("llcp_link_proc_rx_pdu (); PAX PDU exchange shall not be used");
1206 break;
1207
1208 case LLCP_PDU_DISC_TYPE:
1209 if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM))
1210 {
1211 llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
1212 }
1213 else
1214 {
1215 p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1216 llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
1217 }
1218 break;
1219
1220 case LLCP_PDU_SNL_TYPE:
1221 p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1222 llcp_sdp_proc_snl ((UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
1223 break;
1224
1225 case LLCP_PDU_AGF_TYPE:
1226 llcp_link_proc_agf_pdu (p_msg);
1227 free_buffer = FALSE;
1228 break;
1229
1230 case LLCP_PDU_UI_TYPE:
1231 llcp_link_proc_ui_pdu (dsap, ssap, 0, NULL, p_msg);
1232 free_buffer = FALSE;
1233 break;
1234
1235 case LLCP_PDU_I_TYPE:
1236 llcp_dlc_proc_i_pdu (dsap, ssap, 0, NULL, p_msg);
1237 free_buffer = FALSE;
1238 break;
1239
1240 default:
1241 p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1242 llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
1243 break;
1244 }
1245
1246 if (free_buffer)
1247 GKI_freebuf (p_msg);
1248 }
1249
1250 /*******************************************************************************
1251 **
1252 ** Function llcp_link_proc_rx_data
1253 **
1254 ** Description Process received data from NFCC and maintain symmetry state
1255 **
1256 ** Returns void
1257 **
1258 *******************************************************************************/
llcp_link_proc_rx_data(BT_HDR * p_msg)1259 static void llcp_link_proc_rx_data (BT_HDR *p_msg)
1260 {
1261 UINT8 *p;
1262 UINT16 pdu_hdr, info_length = 0;
1263 UINT8 dsap, ptype, ssap;
1264 BOOLEAN free_buffer = TRUE;
1265 BOOLEAN frame_error = FALSE;
1266
1267 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT)
1268 {
1269 llcp_link_stop_link_timer ();
1270
1271 if ( (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
1272 &&(llcp_cb.lcb.sig_xmit_q.count == 0) )
1273 {
1274 /* this indicates that DISC PDU had been sent out to peer */
1275 /* initiator may wait for SYMM PDU */
1276 llcp_link_process_link_timeout ();
1277 }
1278 else
1279 {
1280 if (p_msg->len < LLCP_PDU_HEADER_SIZE)
1281 {
1282 LLCP_TRACE_ERROR1 ("Received too small PDU: got %d bytes", p_msg->len);
1283 frame_error = TRUE;
1284 }
1285 else
1286 {
1287 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
1288 BE_STREAM_TO_UINT16 (pdu_hdr, p );
1289
1290 dsap = LLCP_GET_DSAP (pdu_hdr);
1291 ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
1292 ssap = LLCP_GET_SSAP (pdu_hdr);
1293
1294 /* get length of information per PDU type */
1295 if ( (ptype == LLCP_PDU_I_TYPE)
1296 ||(ptype == LLCP_PDU_RR_TYPE)
1297 ||(ptype == LLCP_PDU_RNR_TYPE) )
1298 {
1299 if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE)
1300 {
1301 info_length = p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
1302 }
1303 else
1304 {
1305 LLCP_TRACE_ERROR0 ("Received I/RR/RNR PDU without sequence");
1306 frame_error = TRUE;
1307 }
1308 }
1309 else
1310 {
1311 info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
1312 }
1313
1314 /* check if length of information is bigger than link MIU */
1315 if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu))
1316 {
1317 LLCP_TRACE_ERROR2 ("Received exceeding MIU (%d): got %d bytes SDU",
1318 llcp_cb.lcb.local_link_miu, info_length);
1319
1320 frame_error = TRUE;
1321 }
1322 else
1323 {
1324 #if (BT_TRACE_VERBOSE == TRUE)
1325 LLCP_TRACE_DEBUG4 ("llcp_link_proc_rx_data (): DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x",
1326 dsap, llcp_pdu_type (ptype), ptype, ssap);
1327 #endif
1328
1329 if (ptype == LLCP_PDU_SYMM_TYPE)
1330 {
1331 if (info_length > 0)
1332 {
1333 LLCP_TRACE_ERROR1 ("Received extra data (%d bytes) in SYMM PDU", info_length);
1334 frame_error = TRUE;
1335 }
1336 }
1337 else
1338 {
1339 /* received other than SYMM */
1340 llcp_link_stop_inactivity_timer ();
1341
1342 llcp_link_proc_rx_pdu (dsap, ptype, ssap, p_msg);
1343 free_buffer = FALSE;
1344 }
1345 }
1346 }
1347
1348 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
1349
1350 /* check if any pending packet */
1351 llcp_link_check_send_data ();
1352 }
1353 }
1354 else
1355 {
1356 LLCP_TRACE_ERROR0 ("Received PDU in state of SYMM_MUST_XMIT_NEXT");
1357 }
1358
1359 if (free_buffer)
1360 GKI_freebuf (p_msg);
1361 }
1362
1363 /*******************************************************************************
1364 **
1365 ** Function llcp_link_get_next_pdu
1366 **
1367 ** Description Get next PDU from link manager or data links w/wo dequeue
1368 **
1369 ** Returns pointer of a PDU to send if length_only is FALSE
1370 ** NULL otherwise
1371 **
1372 *******************************************************************************/
llcp_link_get_next_pdu(BOOLEAN length_only,UINT16 * p_next_pdu_length)1373 static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length)
1374 {
1375 BT_HDR *p_msg;
1376 int count, xx;
1377 tLLCP_APP_CB *p_app_cb;
1378
1379 /* processing signalling PDU first */
1380 if (llcp_cb.lcb.sig_xmit_q.p_first)
1381 {
1382 if (length_only)
1383 {
1384 p_msg = (BT_HDR*) llcp_cb.lcb.sig_xmit_q.p_first;
1385 *p_next_pdu_length = p_msg->len;
1386 return NULL;
1387 }
1388 else
1389 p_msg = (BT_HDR*) GKI_dequeue (&llcp_cb.lcb.sig_xmit_q);
1390
1391 return p_msg;
1392 }
1393 else
1394 {
1395 /* transmitting logical data link and data link connection equaly */
1396 for (xx = 0; xx < 2; xx++)
1397 {
1398 if (!llcp_cb.lcb.ll_served)
1399 {
1400 /* Get one from logical link connection */
1401 for (count = 0; count < LLCP_NUM_SAPS; count++)
1402 {
1403 /* round robin schedule without priority */
1404 p_app_cb = llcp_util_get_app_cb (llcp_cb.lcb.ll_idx);
1405
1406 if ( (p_app_cb)
1407 &&(p_app_cb->p_app_cback)
1408 &&(p_app_cb->ui_xmit_q.count) )
1409 {
1410 if (length_only)
1411 {
1412 /* don't alternate next data link to return the same length of PDU */
1413 p_msg = (BT_HDR *) p_app_cb->ui_xmit_q.p_first;
1414 *p_next_pdu_length = p_msg->len;
1415 return NULL;
1416 }
1417 else
1418 {
1419 /* check data link connection first in next time */
1420 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1421
1422 p_msg = (BT_HDR*) GKI_dequeue (&p_app_cb->ui_xmit_q);
1423 llcp_cb.total_tx_ui_pdu--;
1424
1425 /* this logical link has been served, so start from next logical link next time */
1426 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1427
1428 return p_msg;
1429 }
1430 }
1431 else
1432 {
1433 /* check next logical link connection */
1434 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1435 }
1436 }
1437
1438 /* no data, so check data link connection if not checked yet */
1439 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1440 }
1441 else
1442 {
1443 /* Get one from data link connection */
1444 for (count = 0; count < LLCP_MAX_DATA_LINK; count++)
1445 {
1446 /* round robin schedule without priority */
1447 if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE)
1448 {
1449 if (length_only)
1450 {
1451 *p_next_pdu_length = llcp_dlc_get_next_pdu_length (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
1452
1453 if (*p_next_pdu_length > 0 )
1454 {
1455 /* don't change data link connection to return the same length of PDU */
1456 return NULL;
1457 }
1458 else
1459 {
1460 /* no data, so check next data link connection */
1461 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1462 }
1463 }
1464 else
1465 {
1466 p_msg = llcp_dlc_get_next_pdu (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
1467
1468 /* this data link has been served, so start from next data link next time */
1469 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1470
1471 if (p_msg)
1472 {
1473 /* serve logical data link next time */
1474 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1475 return p_msg;
1476 }
1477 }
1478 }
1479 else
1480 {
1481 /* check next data link connection */
1482 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1483 }
1484 }
1485
1486 /* if all of data link connection doesn't have data to send */
1487 if (count >= LLCP_MAX_DATA_LINK)
1488 {
1489 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1490 }
1491 }
1492 }
1493 }
1494
1495 /* nothing to send */
1496 *p_next_pdu_length = 0;
1497 return NULL;
1498 }
1499
1500 /*******************************************************************************
1501 **
1502 ** Function llcp_link_build_next_pdu
1503 **
1504 ** Description Build a PDU from Link Manager and Data Link
1505 ** Perform aggregation procedure if necessary
1506 **
1507 ** Returns BT_HDR* if sent any PDU
1508 **
1509 *******************************************************************************/
llcp_link_build_next_pdu(BT_HDR * p_pdu)1510 static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_pdu)
1511 {
1512 BT_HDR *p_agf = NULL, *p_msg = NULL, *p_next_pdu;
1513 UINT8 *p, ptype;
1514 UINT16 next_pdu_length, pdu_hdr;
1515
1516 LLCP_TRACE_DEBUG0 ("llcp_link_build_next_pdu ()");
1517
1518 /* add any pending SNL PDU into sig_xmit_q for transmitting */
1519 llcp_sdp_check_send_snl ();
1520
1521 if (p_pdu)
1522 {
1523 /* get PDU type */
1524 p = (UINT8 *) (p_pdu + 1) + p_pdu->offset;
1525 BE_STREAM_TO_UINT16 (pdu_hdr, p);
1526
1527 ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
1528
1529 if (ptype == LLCP_PDU_AGF_TYPE)
1530 {
1531 /* add more PDU into this AGF PDU */
1532 p_agf = p_pdu;
1533 }
1534 else
1535 {
1536 p_msg = p_pdu;
1537 }
1538 }
1539 else
1540 {
1541 /* Get a PDU from link manager or data links */
1542 p_msg = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
1543
1544 if (!p_msg)
1545 {
1546 return NULL;
1547 }
1548 }
1549
1550 /* Get length of next PDU from link manager or data links without dequeue */
1551 llcp_link_get_next_pdu (TRUE, &next_pdu_length);
1552 while (next_pdu_length > 0)
1553 {
1554 /* if it's first visit */
1555 if (!p_agf)
1556 {
1557 /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
1558 if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
1559 {
1560 p_agf = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
1561 if (p_agf)
1562 {
1563 p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1564
1565 p = (UINT8 *) (p_agf + 1) + p_agf->offset;
1566
1567 UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM ));
1568 UINT16_TO_BE_STREAM (p, p_msg->len);
1569 memcpy(p, (UINT8 *) (p_msg + 1) + p_msg->offset, p_msg->len);
1570
1571 p_agf->len = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
1572
1573 GKI_freebuf (p_msg);
1574 p_msg = p_agf;
1575 }
1576 else
1577 {
1578 LLCP_TRACE_ERROR0 ("llcp_link_build_next_pdu (): Out of buffer");
1579 return p_msg;
1580 }
1581 }
1582 else
1583 {
1584 break;
1585 }
1586 }
1587
1588 /* if next PDU fits into MIU, copy the next PDU into AGF */
1589 if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
1590 {
1591 /* Get a next PDU from link manager or data links */
1592 p_next_pdu = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
1593
1594 p = (UINT8 *) (p_agf + 1) + p_agf->offset + p_agf->len;
1595
1596 UINT16_TO_BE_STREAM (p, p_next_pdu->len);
1597 memcpy (p, (UINT8 *) (p_next_pdu + 1) + p_next_pdu->offset, p_next_pdu->len);
1598
1599 p_agf->len += 2 + p_next_pdu->len;
1600
1601 GKI_freebuf (p_next_pdu);
1602
1603 /* Get next PDU length from link manager or data links without dequeue */
1604 llcp_link_get_next_pdu (TRUE, &next_pdu_length);
1605 }
1606 else
1607 {
1608 break;
1609 }
1610 }
1611
1612 if (p_agf)
1613 return p_agf;
1614 else
1615 return p_msg;
1616 }
1617
1618 /*******************************************************************************
1619 **
1620 ** Function llcp_link_send_to_lower
1621 **
1622 ** Description Send PDU to lower layer
1623 **
1624 ** Returns void
1625 **
1626 *******************************************************************************/
llcp_link_send_to_lower(BT_HDR * p_pdu)1627 static void llcp_link_send_to_lower (BT_HDR *p_pdu)
1628 {
1629 #if (BT_TRACE_PROTOCOL == TRUE)
1630 DispLLCP (p_pdu, FALSE);
1631 #endif
1632
1633 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
1634
1635 NFC_SendData (NFC_RF_CONN_ID, p_pdu);
1636 }
1637
1638 /*******************************************************************************
1639 **
1640 ** Function llcp_link_connection_cback
1641 **
1642 ** Description processing incoming data
1643 **
1644 ** Returns void
1645 **
1646 *******************************************************************************/
llcp_link_connection_cback(UINT8 conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)1647 void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
1648 {
1649 if (event == NFC_DATA_CEVT)
1650 {
1651 #if (BT_TRACE_PROTOCOL == TRUE)
1652 DispLLCP ((BT_HDR *)p_data->data.p_data, TRUE);
1653 #endif
1654 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
1655 {
1656 /* respoding SYMM while LLCP is deactivated but RF link is not deactivated yet */
1657 llcp_link_send_SYMM ();
1658 GKI_freebuf ((BT_HDR *) p_data->data.p_data);
1659 }
1660 else
1661 {
1662 llcp_link_proc_rx_data ((BT_HDR *) p_data->data.p_data);
1663 }
1664 }
1665 else if (event == NFC_ERROR_CEVT)
1666 {
1667 /* RF interface specific status code */
1668 llcp_link_deactivate (*(UINT8*) p_data);
1669 }
1670 else if (event == NFC_DEACTIVATE_CEVT)
1671 {
1672 if ( (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
1673 &&(!llcp_cb.lcb.is_initiator) )
1674 {
1675 /* peer initiates NFC link deactivation before timeout */
1676 llcp_link_stop_link_timer ();
1677 llcp_link_process_link_timeout ();
1678 }
1679 else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
1680 {
1681 llcp_link_deactivate (LLCP_LINK_RF_LINK_LOSS_ERR);
1682 }
1683 NFC_SetStaticRfCback (NULL);
1684 }
1685
1686 /* LLCP ignores the following events
1687
1688 NFC_CONN_CREATE_CEVT
1689 NFC_CONN_CLOSE_CEVT
1690 */
1691 }
1692
1693 #if (BT_TRACE_VERBOSE == TRUE)
1694 /*******************************************************************************
1695 **
1696 ** Function llcp_pdu_type
1697 **
1698 ** Description
1699 **
1700 ** Returns string of PDU type
1701 **
1702 *******************************************************************************/
llcp_pdu_type(UINT8 ptype)1703 static char *llcp_pdu_type (UINT8 ptype)
1704 {
1705 switch(ptype)
1706 {
1707 case LLCP_PDU_SYMM_TYPE:
1708 return "SYMM";
1709 case LLCP_PDU_PAX_TYPE:
1710 return "PAX";
1711 case LLCP_PDU_AGF_TYPE:
1712 return "AGF";
1713 case LLCP_PDU_UI_TYPE:
1714 return "UI";
1715 case LLCP_PDU_CONNECT_TYPE:
1716 return "CONNECT";
1717 case LLCP_PDU_DISC_TYPE:
1718 return "DISC";
1719 case LLCP_PDU_CC_TYPE:
1720 return "CC";
1721 case LLCP_PDU_DM_TYPE:
1722 return "DM";
1723 case LLCP_PDU_FRMR_TYPE:
1724 return "FRMR";
1725 case LLCP_PDU_SNL_TYPE:
1726 return "SNL";
1727 case LLCP_PDU_I_TYPE:
1728 return "I";
1729 case LLCP_PDU_RR_TYPE:
1730 return "RR";
1731 case LLCP_PDU_RNR_TYPE:
1732 return "RNR";
1733
1734 default:
1735 return "RESERVED";
1736 }
1737 }
1738
1739 #endif
1740
1741