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