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 Data Link Connection Management
22 *
23 ******************************************************************************/
24
25 #include <string.h>
26 #include "gki.h"
27 #include "nfc_target.h"
28 #include "bt_types.h"
29 #include "llcp_int.h"
30 #include "llcp_defs.h"
31 #include "nfc_int.h"
32
33 static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
34 static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
35 static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
36 static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
37 static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
38
39 #if (BT_TRACE_VERBOSE == TRUE)
40 static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state);
41 static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event);
42 #endif
43
44 /*******************************************************************************
45 **
46 ** Function llcp_dlsm_execute
47 **
48 ** Description This function executes the state machine for data link connection.
49 **
50 ** Returns tLLCP_STATUS
51 **
52 *******************************************************************************/
llcp_dlsm_execute(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)53 tLLCP_STATUS llcp_dlsm_execute (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
54 {
55 tLLCP_STATUS status;
56
57 #if (BT_TRACE_VERBOSE == TRUE)
58 LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %s, evt: %s",
59 p_dlcb->local_sap,
60 llcp_dlsm_get_state_name (p_dlcb->state),
61 llcp_dlsm_get_event_name (event));
62 #else
63 LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %d, evt: %d", p_dlcb->local_sap, p_dlcb->state, event);
64 #endif
65
66 switch (p_dlcb->state)
67 {
68 case LLCP_DLC_STATE_IDLE:
69 status = llcp_dlsm_idle (p_dlcb, event, p_data);
70 break;
71
72 case LLCP_DLC_STATE_W4_REMOTE_RESP:
73 status = llcp_dlsm_w4_remote_resp (p_dlcb, event, p_data);
74 break;
75
76 case LLCP_DLC_STATE_W4_LOCAL_RESP:
77 status = llcp_dlsm_w4_local_resp (p_dlcb, event, p_data);
78 break;
79
80 case LLCP_DLC_STATE_CONNECTED:
81 status = llcp_dlsm_connected (p_dlcb, event, p_data);
82 break;
83
84 case LLCP_DLC_STATE_W4_REMOTE_DM:
85 status = llcp_dlsm_w4_remote_dm (p_dlcb, event, p_data);
86 break;
87
88 default:
89 status = LLCP_STATUS_FAIL;
90 break;
91 }
92
93 return status;
94 }
95
96 /*******************************************************************************
97 **
98 ** Function llcp_dlsm_idle
99 **
100 ** Description Data link connection is in idle state
101 **
102 ** Returns tLLCP_STATUS
103 **
104 *******************************************************************************/
llcp_dlsm_idle(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)105 static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
106 {
107 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
108 tLLCP_SAP_CBACK_DATA data;
109 tLLCP_CONNECTION_PARAMS *p_params;
110
111 switch (event)
112 {
113 case LLCP_DLC_EVENT_API_CONNECT_REQ:
114
115 /* upper layer requests to create data link connection */
116 p_params = (tLLCP_CONNECTION_PARAMS *)p_data;
117
118 status = llcp_util_send_connect (p_dlcb, p_params);
119
120 if (status == LLCP_STATUS_SUCCESS)
121 {
122 p_dlcb->local_miu = p_params->miu;
123 p_dlcb->local_rw = p_params->rw;
124
125 /* wait for response from peer device */
126 p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_RESP;
127
128 nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
129 (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
130 }
131 break;
132
133 case LLCP_DLC_EVENT_PEER_CONNECT_IND:
134
135 /* peer device requests to create data link connection */
136 p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
137
138 if (p_params->miu > llcp_cb.lcb.peer_miu)
139 {
140 LLCP_TRACE_WARNING0 ("llcp_dlsm_idle (): Peer sent data link MIU bigger than peer's link MIU");
141 p_params->miu = llcp_cb.lcb.peer_miu;
142 }
143
144 data.connect_ind.event = LLCP_SAP_EVT_CONNECT_IND;
145 data.connect_ind.remote_sap = p_dlcb->remote_sap;
146 data.connect_ind.local_sap = p_dlcb->local_sap;
147 data.connect_ind.miu = p_params->miu;
148 data.connect_ind.rw = p_params->rw;
149 data.connect_ind.p_service_name = p_params->sn;
150 data.connect_ind.server_sap = p_dlcb->local_sap;
151
152 p_dlcb->remote_miu = p_params->miu;
153 p_dlcb->remote_rw = p_params->rw;
154
155 LLCP_TRACE_DEBUG2 ("llcp_dlsm_idle (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
156
157 /* wait for response from upper layer */
158 p_dlcb->state = LLCP_DLC_STATE_W4_LOCAL_RESP;
159
160 nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
161 (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
162
163 (*p_dlcb->p_app_cb->p_app_cback) (&data);
164
165 break;
166
167 default:
168 LLCP_TRACE_ERROR0 ("llcp_dlsm_idle (): Unexpected event");
169 status = LLCP_STATUS_FAIL;
170 break;
171 }
172
173 return status;
174 }
175
176 /*******************************************************************************
177 **
178 ** Function llcp_dlsm_w4_remote_resp
179 **
180 ** Description data link connection is waiting for connection confirm from peer
181 **
182 ** Returns tLLCP_STATUS
183 **
184 *******************************************************************************/
llcp_dlsm_w4_remote_resp(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)185 static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
186 {
187 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
188 tLLCP_SAP_CBACK_DATA data;
189 tLLCP_CONNECTION_PARAMS *p_params;
190
191 switch (event)
192 {
193 case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
194
195 /* peer device accepted data link connection */
196 nfc_stop_quick_timer (&p_dlcb->timer);
197
198 p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
199
200 /* data link MIU must be up to link MIU */
201 if (p_params->miu > llcp_cb.lcb.peer_miu)
202 {
203 LLCP_TRACE_WARNING0 ("llcp_dlsm_w4_remote_resp (): Peer sent data link MIU bigger than peer's link MIU");
204 p_params->miu = llcp_cb.lcb.peer_miu;
205 }
206
207 p_dlcb->remote_miu = p_params->miu;
208 p_dlcb->remote_rw = p_params->rw;
209
210 LLCP_TRACE_DEBUG2 ("llcp_dlsm_w4_remote_resp (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
211
212 p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
213 llcp_util_adjust_dl_rx_congestion ();
214
215 data.connect_resp.event = LLCP_SAP_EVT_CONNECT_RESP;
216 data.connect_resp.remote_sap = p_dlcb->remote_sap;
217 data.connect_resp.local_sap = p_dlcb->local_sap;
218 data.connect_resp.miu = p_params->miu;
219 data.connect_resp.rw = p_params->rw;
220
221 (*p_dlcb->p_app_cb->p_app_cback) (&data);
222
223 if (llcp_cb.overall_rx_congested)
224 {
225 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
226 }
227 break;
228
229 case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
230 case LLCP_DLC_EVENT_TIMEOUT:
231
232 /* peer device rejected connection or didn't respond */
233 data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
234 data.disconnect_resp.local_sap = p_dlcb->local_sap;
235 data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
236 data.disconnect_resp.reason = *((UINT8*) p_data);
237 (*p_dlcb->p_app_cb->p_app_cback) (&data);
238
239 /* stop timer, flush any pending data in queue and deallocate control block */
240 llcp_util_deallocate_data_link (p_dlcb);
241
242 llcp_util_adjust_dl_rx_congestion ();
243 break;
244
245 case LLCP_DLC_EVENT_FRAME_ERROR:
246 case LLCP_DLC_EVENT_LINK_ERROR:
247
248 /* received bad frame or link is deactivated */
249 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
250 data.disconnect_ind.local_sap = p_dlcb->local_sap;
251 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
252 (*p_dlcb->p_app_cb->p_app_cback) (&data);
253
254 llcp_util_deallocate_data_link (p_dlcb);
255 llcp_util_adjust_dl_rx_congestion ();
256 break;
257
258 default:
259 LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_resp (): Unexpected event");
260 status = LLCP_STATUS_FAIL;
261 break;
262 }
263
264 return status;
265 }
266
267 /*******************************************************************************
268 **
269 ** Function llcp_dlsm_w4_local_resp
270 **
271 ** Description data link connection is waiting for connection confirm from application
272 **
273 ** Returns tLLCP_STATUS
274 **
275 *******************************************************************************/
llcp_dlsm_w4_local_resp(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)276 static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
277 {
278 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
279 tLLCP_CONNECTION_PARAMS *p_params;
280 tLLCP_SAP_CBACK_DATA data;
281 UINT8 reason;
282
283 switch (event)
284 {
285 case LLCP_DLC_EVENT_API_CONNECT_CFM:
286
287 /* upper layer accepted data link connection */
288 nfc_stop_quick_timer (&p_dlcb->timer);
289
290 p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
291
292 p_dlcb->local_miu = p_params->miu;
293 p_dlcb->local_rw = p_params->rw;
294
295 p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
296
297 if (llcp_cb.overall_rx_congested)
298 {
299 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
300 }
301
302 status = llcp_util_send_cc (p_dlcb, p_params);
303
304 if (status == LLCP_STATUS_SUCCESS)
305 {
306 llcp_util_adjust_dl_rx_congestion ();
307 }
308 else
309 {
310 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
311 data.disconnect_ind.local_sap = p_dlcb->local_sap;
312 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
313 (*p_dlcb->p_app_cb->p_app_cback) (&data);
314
315 llcp_util_deallocate_data_link (p_dlcb);
316 }
317 break;
318
319 case LLCP_DLC_EVENT_API_CONNECT_REJECT:
320 case LLCP_DLC_EVENT_TIMEOUT:
321
322 if (event == LLCP_DLC_EVENT_TIMEOUT)
323 reason = LLCP_SAP_DM_REASON_TEMP_REJECT_THIS;
324 else
325 reason = *((UINT8*) p_data);
326
327 /* upper layer rejected connection or didn't respond */
328 llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, reason);
329
330 /* stop timer, flush any pending data in queue and deallocate control block */
331 llcp_util_deallocate_data_link (p_dlcb);
332 llcp_util_adjust_dl_rx_congestion ();
333 break;
334
335 case LLCP_DLC_EVENT_FRAME_ERROR:
336 case LLCP_DLC_EVENT_LINK_ERROR:
337
338 /* received bad frame or link is deactivated */
339 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
340 data.disconnect_ind.local_sap = p_dlcb->local_sap;
341 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
342 (*p_dlcb->p_app_cb->p_app_cback) (&data);
343
344 llcp_util_deallocate_data_link (p_dlcb);
345 llcp_util_adjust_dl_rx_congestion ();
346 break;
347
348 default:
349 LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_local_resp (): Unexpected event");
350 status = LLCP_STATUS_FAIL;
351 break;
352 }
353
354 return status;
355 }
356
357 /*******************************************************************************
358 **
359 ** Function llcp_dlsm_connected
360 **
361 ** Description data link connection is connected
362 **
363 ** Returns tLLCP_STATUS
364 **
365 *******************************************************************************/
llcp_dlsm_connected(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)366 static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
367 {
368 BOOLEAN flush;
369 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
370 tLLCP_SAP_CBACK_DATA data;
371
372 switch (event)
373 {
374 case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
375
376 /* upper layer requests to disconnect */
377 flush = *(BOOLEAN*) (p_data);
378
379 /*
380 ** if upper layer asks to discard any pending data
381 ** or there is no pending data/ack to send and it is not waiting for ack
382 */
383 if ( (flush)
384 ||( (p_dlcb->i_xmit_q.count == 0)
385 &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
386 &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq) ) )
387 {
388 /* wait for disconnect response */
389 p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_DM;
390
391 llcp_util_send_disc (p_dlcb->remote_sap, p_dlcb->local_sap );
392
393 nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
394 (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
395 }
396 else
397 {
398 /* set flag to send DISC when tx queue is empty */
399 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_DISC;
400 }
401 break;
402
403 case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
404
405 /* peer device requests to disconnect */
406
407 /* send disconnect response and notify upper layer */
408 llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
409
410 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
411 data.disconnect_ind.local_sap = p_dlcb->local_sap;
412 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
413 (*p_dlcb->p_app_cb->p_app_cback) (&data);
414
415 llcp_util_deallocate_data_link (p_dlcb);
416 llcp_util_adjust_dl_rx_congestion ();
417 break;
418
419 case LLCP_DLC_EVENT_API_DATA_REQ:
420
421 /* upper layer requests to send data */
422
423 /* if peer device can receive data */
424 if (p_dlcb->remote_rw)
425 {
426 /* enqueue data and check if data can be sent */
427 GKI_enqueue (&p_dlcb->i_xmit_q, p_data);
428 llcp_cb.total_tx_i_pdu++;
429
430 llcp_link_check_send_data ();
431
432 if ( (p_dlcb->is_tx_congested)
433 ||(llcp_cb.overall_tx_congested)
434 ||(p_dlcb->remote_busy)
435 ||(p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw) ) /*if enough data to send next round */
436 {
437 LLCP_TRACE_DEBUG3 ("llcp_dlsm_connected (): Data link (SSAP:DSAP=0x%X:0x%X) congested: xmit_q.count=%d",
438 p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
439
440 /* set congested here so overall congestion check routine will not report event again */
441 p_dlcb->is_tx_congested = TRUE;
442 status = LLCP_STATUS_CONGESTED;
443 }
444 }
445 else
446 {
447 LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Remote RW is zero: discard data");
448 /* buffer will be freed when returned to API function */
449 status = LLCP_STATUS_FAIL;
450 }
451 break;
452
453 case LLCP_DLC_EVENT_PEER_DATA_IND:
454 /* peer device sends data so notify upper layer to read data from data link connection */
455
456 data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
457 data.data_ind.local_sap = p_dlcb->local_sap;
458 data.data_ind.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
459 data.data_ind.remote_sap = p_dlcb->remote_sap;
460
461 (*p_dlcb->p_app_cb->p_app_cback) (&data);
462 break;
463
464 case LLCP_DLC_EVENT_FRAME_ERROR:
465 case LLCP_DLC_EVENT_LINK_ERROR:
466
467 /* received bad frame or link is deactivated */
468 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
469 data.disconnect_ind.local_sap = p_dlcb->local_sap;
470 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
471 (*p_dlcb->p_app_cb->p_app_cback) (&data);
472
473 llcp_util_deallocate_data_link (p_dlcb);
474 llcp_util_adjust_dl_rx_congestion ();
475 break;
476
477 default:
478 LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Unexpected event");
479 status = LLCP_STATUS_FAIL;
480 break;
481 }
482
483 return status;
484 }
485
486 /*******************************************************************************
487 **
488 ** Function llcp_dlsm_w4_remote_dm
489 **
490 ** Description data link connection is waiting for disconnection confirm from peer
491 **
492 ** Returns tLLCP_STATUS
493 **
494 *******************************************************************************/
llcp_dlsm_w4_remote_dm(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)495 static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
496 {
497 tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
498 tLLCP_SAP_CBACK_DATA data;
499
500 switch (event)
501 {
502 case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
503 case LLCP_DLC_EVENT_TIMEOUT:
504
505 /* peer device sends disconnect response or didn't responde */
506 data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
507 data.disconnect_resp.local_sap = p_dlcb->local_sap;
508 data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
509 data.disconnect_resp.reason = LLCP_SAP_DM_REASON_RESP_DISC;
510 (*p_dlcb->p_app_cb->p_app_cback) (&data);
511
512 llcp_util_deallocate_data_link (p_dlcb);
513 llcp_util_adjust_dl_rx_congestion ();
514 break;
515
516 case LLCP_DLC_EVENT_FRAME_ERROR:
517 case LLCP_DLC_EVENT_LINK_ERROR:
518
519 /* received bad frame or link is deactivated */
520 data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
521 data.disconnect_ind.local_sap = p_dlcb->local_sap;
522 data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
523 (*p_dlcb->p_app_cb->p_app_cback) (&data);
524
525 llcp_util_deallocate_data_link (p_dlcb);
526 llcp_util_adjust_dl_rx_congestion ();
527 break;
528
529 case LLCP_DLC_EVENT_PEER_DATA_IND:
530 break;
531
532 case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
533 /* it's race condition, send disconnect response and wait for DM */
534 llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
535 break;
536
537 default:
538 LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_dm (): Unexpected event");
539 status = LLCP_STATUS_FAIL;
540 break;
541 }
542
543 return status;
544 }
545
546 /*******************************************************************************
547 **
548 ** Function llcp_dlc_find_dlcb_by_local_sap
549 **
550 ** Description Find tLLCP_DLCB by local SAP and remote SAP
551 ** if remote_sap is LLCP_INVALID_SAP, it will return a DLCB which
552 ** is waiting for CC from peer.
553 **
554 ** Returns tLLCP_DLCB *
555 **
556 *******************************************************************************/
llcp_dlc_find_dlcb_by_sap(UINT8 local_sap,UINT8 remote_sap)557 tLLCP_DLCB *llcp_dlc_find_dlcb_by_sap (UINT8 local_sap, UINT8 remote_sap)
558 {
559 int i;
560
561 for (i = 0; i < LLCP_MAX_DATA_LINK; i++)
562 {
563 if ( (llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE)
564 &&(llcp_cb.dlcb[i].local_sap == local_sap) )
565 {
566 if ((remote_sap == LLCP_INVALID_SAP) && (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP))
567 {
568 /* Remote SAP has not been finalized because we are watiing for CC */
569 return (&llcp_cb.dlcb[i]);
570 }
571 else if (llcp_cb.dlcb[i].remote_sap == remote_sap)
572 {
573 return (&llcp_cb.dlcb[i]);
574 }
575 }
576 }
577 return NULL;
578 }
579
580 /*******************************************************************************
581 **
582 ** Function llcp_dlc_flush_q
583 **
584 ** Description Free buffers in tx and rx queue in data link
585 **
586 ** Returns void
587 **
588 *******************************************************************************/
llcp_dlc_flush_q(tLLCP_DLCB * p_dlcb)589 void llcp_dlc_flush_q (tLLCP_DLCB *p_dlcb)
590 {
591 if (p_dlcb)
592 {
593 LLCP_TRACE_DEBUG1 ("llcp_dlc_flush_q (): local SAP:0x%02X", p_dlcb->local_sap);
594
595 /* Release any held buffers */
596 while (p_dlcb->i_xmit_q.p_first)
597 {
598 GKI_freebuf (GKI_dequeue (&p_dlcb->i_xmit_q));
599 llcp_cb.total_tx_i_pdu--;
600 }
601
602 /* discard any received I PDU on data link including in AGF */
603 LLCP_FlushDataLinkRxData (p_dlcb->local_sap, p_dlcb->remote_sap);
604 }
605 else
606 {
607 LLCP_TRACE_ERROR0 ("llcp_dlc_flush_q (): p_dlcb is NULL");
608 }
609 }
610
611 /*******************************************************************************
612 **
613 ** Function llcp_dlc_proc_connect_pdu
614 **
615 ** Description Process CONNECT PDU
616 **
617 ** Returns void
618 **
619 *******************************************************************************/
llcp_dlc_proc_connect_pdu(UINT8 dsap,UINT8 ssap,UINT16 length,UINT8 * p_data)620 static void llcp_dlc_proc_connect_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
621 {
622 tLLCP_DLCB *p_dlcb;
623 tLLCP_STATUS status;
624 tLLCP_APP_CB *p_app_cb;
625
626 tLLCP_CONNECTION_PARAMS params;
627
628 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_connect_pdu ()");
629
630 p_app_cb = llcp_util_get_app_cb (dsap);
631
632 if ( (p_app_cb == NULL)
633 ||(p_app_cb->p_app_cback == NULL)
634 ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0) )
635 {
636 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered SAP:0x%x", dsap);
637 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
638 return;
639 }
640
641 /* parse CONNECT PDU and get connection parameters */
642 if (llcp_util_parse_connect (p_data, length, ¶ms) != LLCP_STATUS_SUCCESS)
643 {
644 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Bad format CONNECT");
645 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
646 return;
647 }
648
649 /* if this is connection by service name */
650 if (dsap == LLCP_SAP_SDP)
651 {
652 /* find registered SAP with service name */
653 if (strlen (params.sn))
654 dsap = llcp_sdp_get_sap_by_name (params.sn, (UINT8) strlen (params.sn));
655 else
656 {
657 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
658 return;
659 }
660 if (dsap == LLCP_SAP_SDP)
661 {
662 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): SDP doesn't accept connection");
663
664 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
665 return;
666 }
667 else if (dsap == 0)
668 {
669 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered Service:%s", params.sn);
670
671 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
672 return;
673 }
674 }
675
676 /* check if any data link */
677 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
678 if (p_dlcb)
679 {
680 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Data link is aleady established");
681 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
682 }
683 else
684 {
685 /* allocate data link connection control block and notify upper layer through state machine */
686 p_dlcb = llcp_util_allocate_data_link (dsap, ssap);
687
688 if (p_dlcb)
689 {
690 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, ¶ms);
691 if (status != LLCP_STATUS_SUCCESS)
692 {
693 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Error in state machine");
694 llcp_util_deallocate_data_link (p_dlcb);
695 }
696 }
697 else
698 {
699 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Out of resource");
700 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY );
701 }
702 }
703 }
704
705 /*******************************************************************************
706 **
707 ** Function llcp_dlc_proc_disc_pdu
708 **
709 ** Description Process DISC PDU
710 **
711 ** Returns void
712 **
713 *******************************************************************************/
llcp_dlc_proc_disc_pdu(UINT8 dsap,UINT8 ssap,UINT16 length,UINT8 * p_data)714 static void llcp_dlc_proc_disc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
715 {
716 tLLCP_DLCB *p_dlcb;
717
718 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_disc_pdu ()");
719
720 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
721 if (p_dlcb)
722 {
723 if (length > 0)
724 {
725 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC PDU", length);
726
727 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
728 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
729 }
730 else
731 {
732 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
733 }
734 }
735 else
736 {
737 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
738 }
739 }
740
741 /*******************************************************************************
742 **
743 ** Function llcp_dlc_proc_cc_pdu
744 **
745 ** Description Process CC PDU
746 **
747 ** Returns void
748 **
749 *******************************************************************************/
llcp_dlc_proc_cc_pdu(UINT8 dsap,UINT8 ssap,UINT16 length,UINT8 * p_data)750 static void llcp_dlc_proc_cc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
751 {
752 tLLCP_DLCB *p_dlcb;
753 tLLCP_CONNECTION_PARAMS params;
754 tLLCP_STATUS status;
755
756 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_cc_pdu ()");
757
758 /* find a DLCB waiting for CC on this local SAP */
759 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
760 if (p_dlcb)
761 {
762 /* The CC may contain a SSAP that is different from the DSAP in the CONNECT */
763 p_dlcb->remote_sap = ssap;
764
765 if (llcp_util_parse_cc (p_data, length, &(params.miu), &(params.rw)) == LLCP_STATUS_SUCCESS)
766 {
767 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, ¶ms);
768 if (status != LLCP_STATUS_SUCCESS)
769 {
770 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_cc_pdu (): Error in state machine");
771 llcp_util_deallocate_data_link (p_dlcb);
772 }
773 }
774 else
775 {
776 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
777 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
778 }
779 }
780 else
781 {
782 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
783 }
784 }
785
786 /*******************************************************************************
787 **
788 ** Function llcp_dlc_proc_dm_pdu
789 **
790 ** Description Process DM PDU
791 **
792 ** Returns void
793 **
794 *******************************************************************************/
llcp_dlc_proc_dm_pdu(UINT8 dsap,UINT8 ssap,UINT16 length,UINT8 * p_data)795 static void llcp_dlc_proc_dm_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
796 {
797 tLLCP_DLCB *p_dlcb;
798
799 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_dm_pdu ()");
800
801 if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE)
802 {
803 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
804 }
805 else
806 {
807 if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC)
808 {
809 /* local device initiated disconnecting */
810 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
811 }
812 else
813 {
814 /* peer device rejected connection with any reason */
815 /* find a DLCB waiting for CC on this local SAP */
816 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
817 }
818
819 if (p_dlcb)
820 {
821 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, p_data); /* passing reason */
822 }
823 else
824 {
825 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
826 }
827 }
828 }
829
830 /*******************************************************************************
831 **
832 ** Function llcp_dlc_proc_i_pdu
833 **
834 ** Description Process I PDU
835 **
836 ** Returns void
837 **
838 *******************************************************************************/
llcp_dlc_proc_i_pdu(UINT8 dsap,UINT8 ssap,UINT16 i_pdu_length,UINT8 * p_i_pdu,BT_HDR * p_msg)839 void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg)
840 {
841 UINT8 *p, *p_dst, send_seq, rcv_seq, error_flags;
842 UINT16 info_len, available_bytes;
843 tLLCP_DLCB *p_dlcb;
844 BOOLEAN appended;
845 BT_HDR *p_last_buf;
846
847 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_i_pdu ()");
848
849 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
850
851 if (p_dlcb)
852 {
853 error_flags = 0;
854
855 if (p_msg)
856 {
857 i_pdu_length = p_msg->len;
858 p_i_pdu = (UINT8 *) (p_msg + 1) + p_msg->offset;
859 }
860
861 info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
862
863 if (info_len > p_dlcb->local_miu)
864 {
865 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d bytes SDU",
866 p_dlcb->local_miu, info_len);
867
868 error_flags |= LLCP_FRMR_I_ERROR_FLAG;
869 }
870
871 /* get sequence numbers */
872 p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
873
874 send_seq = LLCP_GET_NS (*p);
875 rcv_seq = LLCP_GET_NR (*p);
876
877 #if (BT_TRACE_VERBOSE == TRUE)
878 LLCP_TRACE_DEBUG6 ("LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
879 send_seq, rcv_seq,
880 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
881 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
882 #endif
883
884 /* if send sequence number, N(S) is not expected one, V(R) */
885 if (p_dlcb->next_rx_seq != send_seq)
886 {
887 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
888 send_seq, p_dlcb->next_rx_seq);
889
890 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
891 }
892 else
893 {
894 /* if peer device sends more than our receiving window size */
895 if ((UINT8) (send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >= p_dlcb->local_rw)
896 {
897 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
898 send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
899
900 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
901 }
902 }
903
904 /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
905 if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
906 != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO)
907 {
908 error_flags |= LLCP_FRMR_R_ERROR_FLAG;
909 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
910 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
911 }
912
913 /* if any error is found */
914 if (error_flags)
915 {
916 llcp_util_send_frmr (p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
917 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
918 }
919 else
920 {
921 /* update local sequence variables */
922 p_dlcb->next_rx_seq = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
923 p_dlcb->rcvd_ack_seq = rcv_seq;
924
925 appended = FALSE;
926
927 /* get last buffer in rx queue */
928 p_last_buf = (BT_HDR *) GKI_getlast (&p_dlcb->i_rx_q);
929
930 if (p_last_buf)
931 {
932 /* get max length to append at the end of buffer */
933 available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
934
935 /* if new UI PDU with length can be attached at the end of buffer */
936 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len)
937 {
938 p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
939
940 /* add length of information in I PDU */
941 UINT16_TO_BE_STREAM (p_dst, info_len);
942
943 /* copy information of I PDU */
944 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
945
946 memcpy (p_dst, p, info_len);
947
948 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
949
950 if (p_msg)
951 {
952 GKI_freebuf (p_msg);
953 p_msg = NULL;
954 }
955
956 appended = TRUE;
957 }
958 }
959
960 /* if it is not available to append */
961 if (!appended)
962 {
963 /* if it's not from AGF PDU */
964 if (p_msg)
965 {
966 /* add length of information in front of information */
967 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
968 UINT16_TO_BE_STREAM (p, info_len);
969
970 p_msg->offset += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
971 p_msg->len -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
972 p_msg->layer_specific = 0;
973 }
974 else
975 {
976 p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
977
978 if (p_msg)
979 {
980 p_dst = (UINT8*) (p_msg + 1);
981
982 /* add length of information in front of information */
983 UINT16_TO_BE_STREAM (p_dst, info_len);
984
985 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
986 memcpy (p_dst, p, info_len);
987
988 p_msg->offset = 0;
989 p_msg->len = LLCP_PDU_AGF_LEN_SIZE + info_len;
990 p_msg->layer_specific = 0;
991 }
992 else
993 {
994 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_i_pdu (): out of buffer");
995 }
996 }
997
998 /* insert I PDU in rx queue */
999 if (p_msg)
1000 {
1001 GKI_enqueue (&p_dlcb->i_rx_q, p_msg);
1002 p_msg = NULL;
1003 llcp_cb.total_rx_i_pdu++;
1004
1005 llcp_util_check_rx_congested_status ();
1006 }
1007 }
1008
1009 p_dlcb->num_rx_i_pdu++;
1010
1011 if ( (!p_dlcb->local_busy)
1012 &&(p_dlcb->num_rx_i_pdu == 1) )
1013 {
1014 /* notify rx data is available so upper layer reads data until queue is empty */
1015 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1016 }
1017
1018 if ( (!p_dlcb->is_rx_congested)
1019 &&(p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold) )
1020 {
1021 LLCP_TRACE_DEBUG2 ("llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, rx_congest_threshold=%d",
1022 p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
1023
1024 /* send RNR */
1025 p_dlcb->is_rx_congested = TRUE;
1026 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1027 }
1028 }
1029 }
1030 else
1031 {
1032 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
1033 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION );
1034 }
1035
1036 if (p_msg)
1037 {
1038 GKI_freebuf (p_msg);
1039 }
1040 }
1041
1042 /*******************************************************************************
1043 **
1044 ** Function llcp_dlc_proc_rr_rnr_pdu
1045 **
1046 ** Description Process RR or RNR PDU
1047 **
1048 ** Returns void
1049 **
1050 *******************************************************************************/
llcp_dlc_proc_rr_rnr_pdu(UINT8 dsap,UINT8 ptype,UINT8 ssap,UINT16 length,UINT8 * p_data)1051 static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1052 {
1053 UINT8 rcv_seq, error_flags;
1054 tLLCP_DLCB *p_dlcb;
1055 BOOLEAN flush = TRUE;
1056 tLLCP_SAP_CBACK_DATA cback_data;
1057
1058 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
1059
1060 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1061 if (p_dlcb != NULL)
1062 {
1063 error_flags = 0;
1064
1065 rcv_seq = LLCP_GET_NR (*p_data);
1066
1067 if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE)
1068 {
1069 error_flags |= LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG;
1070 }
1071
1072 /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
1073 if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
1074 != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
1075 {
1076 error_flags |= LLCP_FRMR_R_ERROR_FLAG;
1077 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
1078 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
1079 }
1080
1081 if (error_flags)
1082 {
1083 llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
1084 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1085 }
1086 else
1087 {
1088 p_dlcb->rcvd_ack_seq = rcv_seq;
1089
1090 #if (BT_TRACE_VERBOSE == TRUE)
1091 LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1092 rcv_seq,
1093 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1094 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1095 #endif
1096
1097 if (ptype == LLCP_PDU_RNR_TYPE)
1098 {
1099 /* if upper layer hasn't get congestion started notification */
1100 if ( (!p_dlcb->remote_busy)
1101 &&(!p_dlcb->is_tx_congested) )
1102 {
1103 LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
1104 p_dlcb->local_sap, p_dlcb->remote_sap,
1105 p_dlcb->i_xmit_q.count);
1106
1107 cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1108 cback_data.congest.local_sap = p_dlcb->local_sap;
1109 cback_data.congest.remote_sap = p_dlcb->remote_sap;
1110 cback_data.congest.is_congested = TRUE;
1111 cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1112
1113 (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1114 }
1115 p_dlcb->remote_busy = TRUE;
1116 }
1117 else
1118 {
1119 /* if upper layer hasn't get congestion ended notification and data link is not congested */
1120 if ( (p_dlcb->remote_busy)
1121 &&(!p_dlcb->is_tx_congested) )
1122 {
1123 LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
1124 p_dlcb->local_sap, p_dlcb->remote_sap,
1125 p_dlcb->i_xmit_q.count);
1126
1127 cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1128 cback_data.congest.local_sap = p_dlcb->local_sap;
1129 cback_data.congest.remote_sap = p_dlcb->remote_sap;
1130 cback_data.congest.is_congested = FALSE;
1131 cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1132
1133 (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1134 }
1135 p_dlcb->remote_busy = FALSE;
1136 }
1137
1138 /* check flag to send DISC when tx queue is empty */
1139 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1140 {
1141 /* if no pending data and all PDU is acked */
1142 if ( (p_dlcb->i_xmit_q.count == 0)
1143 &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1144 &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq) )
1145 {
1146 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1147 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1148 }
1149 }
1150 }
1151 }
1152 else
1153 {
1154 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
1155 }
1156 }
1157
1158 /*******************************************************************************
1159 **
1160 ** Function llcp_dlc_proc_rx_pdu
1161 **
1162 ** Description Process PDU for data link
1163 **
1164 ** Returns void
1165 **
1166 *******************************************************************************/
llcp_dlc_proc_rx_pdu(UINT8 dsap,UINT8 ptype,UINT8 ssap,UINT16 length,UINT8 * p_data)1167 void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1168 {
1169 tLLCP_DLCB *p_dlcb;
1170
1171 LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
1172 dsap, ptype, ssap);
1173
1174 if (dsap == LLCP_SAP_LM)
1175 {
1176 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
1177 return;
1178 }
1179
1180 switch (ptype)
1181 {
1182 case LLCP_PDU_CONNECT_TYPE:
1183 llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
1184 break;
1185
1186 case LLCP_PDU_DISC_TYPE:
1187 llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
1188 break;
1189
1190 case LLCP_PDU_CC_TYPE:
1191 llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
1192 break;
1193
1194 case LLCP_PDU_DM_TYPE:
1195 llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
1196 break;
1197
1198 case LLCP_PDU_FRMR_TYPE:
1199 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1200 if (p_dlcb)
1201 {
1202 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1203 }
1204 break;
1205
1206 case LLCP_PDU_RR_TYPE:
1207 case LLCP_PDU_RNR_TYPE:
1208 llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
1209 break;
1210
1211 default:
1212 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
1213
1214 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1215 if (p_dlcb)
1216 {
1217 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
1218 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1219 }
1220 break;
1221 }
1222 }
1223
1224 /*******************************************************************************
1225 **
1226 ** Function llcp_dlc_check_to_send_rr_rnr
1227 **
1228 ** Description Send RR or RNR if necessary
1229 **
1230 ** Returns void
1231 **
1232 *******************************************************************************/
llcp_dlc_check_to_send_rr_rnr(void)1233 void llcp_dlc_check_to_send_rr_rnr (void)
1234 {
1235 UINT8 idx;
1236 BOOLEAN flush = TRUE;
1237
1238 LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
1239
1240 /*
1241 ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
1242 ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
1243 ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
1244 **
1245 ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
1246 ** V(R).
1247 */
1248 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
1249 {
1250 if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
1251 {
1252 llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
1253
1254 /* check flag to send DISC when tx queue is empty */
1255 if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1256 {
1257 /* if no pending data and all PDU is acked */
1258 if ( (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
1259 &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
1260 &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq) )
1261 {
1262 llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1263 llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1264 }
1265 }
1266 }
1267 }
1268 }
1269
1270 /*******************************************************************************
1271 **
1272 ** Function llcp_dlc_is_rw_open
1273 **
1274 ** Description check if receive window is open in remote
1275 **
1276 ** Returns TRUE if remote can receive more data
1277 **
1278 *******************************************************************************/
llcp_dlc_is_rw_open(tLLCP_DLCB * p_dlcb)1279 BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
1280 {
1281 if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
1282 {
1283 return TRUE;
1284 }
1285 else
1286 {
1287 LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
1288 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
1289 return FALSE;
1290 }
1291 }
1292
1293 /*******************************************************************************
1294 **
1295 ** Function llcp_dlc_get_next_pdu
1296 **
1297 ** Description Get a PDU from tx queue of data link
1298 **
1299 ** Returns BT_HDR*
1300 **
1301 *******************************************************************************/
llcp_dlc_get_next_pdu(tLLCP_DLCB * p_dlcb)1302 BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
1303 {
1304 BT_HDR *p_msg = NULL;
1305 BOOLEAN flush = TRUE;
1306 tLLCP_SAP_CBACK_DATA data;
1307
1308 #if (BT_TRACE_VERBOSE == TRUE)
1309 UINT8 send_seq = p_dlcb->next_tx_seq;
1310 #endif
1311
1312 /* if there is data to send and remote device can receive it */
1313 if ( (p_dlcb->i_xmit_q.count)
1314 &&(!p_dlcb->remote_busy)
1315 &&(llcp_dlc_is_rw_open (p_dlcb)) )
1316 {
1317 p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
1318 llcp_cb.total_tx_i_pdu--;
1319
1320 if (p_msg->offset >= LLCP_MIN_OFFSET)
1321 {
1322 /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
1323 llcp_util_build_info_pdu (p_dlcb, p_msg);
1324
1325 p_dlcb->next_tx_seq = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
1326
1327 #if (BT_TRACE_VERBOSE == TRUE)
1328 LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1329 send_seq, p_dlcb->next_rx_seq,
1330 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1331 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1332 #endif
1333 }
1334 else
1335 {
1336 LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
1337 p_msg->offset, LLCP_MIN_OFFSET );
1338 GKI_freebuf (p_msg);
1339 p_msg = NULL;
1340 }
1341 }
1342
1343 /* if tx queue is empty and all PDU is acknowledged */
1344 if ( (p_dlcb->i_xmit_q.count == 0)
1345 &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1346 &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq) )
1347 {
1348 /* check flag to send DISC */
1349 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1350 {
1351 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1352 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1353 }
1354
1355 /* check flag to notify upper layer */
1356 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
1357 {
1358 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1359
1360 data.tx_complete.event = LLCP_SAP_EVT_TX_COMPLETE;
1361 data.tx_complete.local_sap = p_dlcb->local_sap;
1362 data.tx_complete.remote_sap = p_dlcb->remote_sap;
1363
1364 (*p_dlcb->p_app_cb->p_app_cback) (&data);
1365 }
1366 }
1367
1368 return p_msg;
1369 }
1370
1371 /*******************************************************************************
1372 **
1373 ** Function llcp_dlc_get_next_pdu_length
1374 **
1375 ** Description return length of PDU which is top in tx queue of data link
1376 **
1377 ** Returns length of PDU
1378 **
1379 *******************************************************************************/
llcp_dlc_get_next_pdu_length(tLLCP_DLCB * p_dlcb)1380 UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
1381 {
1382 BT_HDR *p_msg;
1383
1384 /* if there is data to send and remote device can receive it */
1385 if ( (p_dlcb->i_xmit_q.count)
1386 &&(!p_dlcb->remote_busy)
1387 &&(llcp_dlc_is_rw_open (p_dlcb)) )
1388 {
1389 p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
1390
1391 return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
1392 }
1393 return 0;
1394 }
1395
1396 #if (BT_TRACE_VERBOSE == TRUE)
1397 /*******************************************************************************
1398 **
1399 ** Function llcp_dlsm_get_state_name
1400 **
1401 ** Description This function returns the state name.
1402 **
1403 ** Returns pointer to the name
1404 **
1405 *******************************************************************************/
llcp_dlsm_get_state_name(tLLCP_DLC_STATE state)1406 static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
1407 {
1408 switch (state)
1409 {
1410 case LLCP_DLC_STATE_IDLE:
1411 return ("IDLE");
1412 case LLCP_DLC_STATE_W4_REMOTE_RESP:
1413 return ("W4_REMOTE_RESP");
1414 case LLCP_DLC_STATE_W4_LOCAL_RESP:
1415 return ("W4_LOCAL_RESP");
1416 case LLCP_DLC_STATE_CONNECTED:
1417 return ("CONNECTED");
1418 case LLCP_DLC_STATE_W4_REMOTE_DM:
1419 return ("W4_REMOTE_DM");
1420 default:
1421 return ("???? UNKNOWN STATE");
1422 }
1423 }
1424
1425 /*******************************************************************************
1426 **
1427 ** Function llcp_dlsm_get_event_name
1428 **
1429 ** Description This function returns the event name.
1430 **
1431 ** Returns pointer to the name
1432 **
1433 *******************************************************************************/
llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event)1434 static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
1435 {
1436 switch (event)
1437 {
1438 case LLCP_DLC_EVENT_API_CONNECT_REQ:
1439 return ("API_CONNECT_REQ");
1440 case LLCP_DLC_EVENT_API_CONNECT_CFM:
1441 return ("API_CONNECT_CFM");
1442 case LLCP_DLC_EVENT_API_CONNECT_REJECT:
1443 return ("API_CONNECT_REJECT");
1444 case LLCP_DLC_EVENT_PEER_CONNECT_IND:
1445 return ("PEER_CONNECT_IND");
1446 case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
1447 return ("PEER_CONNECT_CFM");
1448
1449 case LLCP_DLC_EVENT_API_DATA_REQ:
1450 return ("API_DATA_REQ");
1451 case LLCP_DLC_EVENT_PEER_DATA_IND:
1452 return ("PEER_DATA_IND");
1453
1454 case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
1455 return ("API_DISCONNECT_REQ");
1456 case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
1457 return ("PEER_DISCONNECT_IND");
1458 case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
1459 return ("PEER_DISCONNECT_RESP");
1460
1461 case LLCP_DLC_EVENT_FRAME_ERROR:
1462 return ("FRAME_ERROR");
1463 case LLCP_DLC_EVENT_LINK_ERROR:
1464 return ("LINK_ERROR");
1465
1466 case LLCP_DLC_EVENT_TIMEOUT:
1467 return ("TIMEOUT");
1468
1469 default:
1470 return ("???? UNKNOWN EVENT");
1471 }
1472 }
1473 #endif /* (BT_TRACE_VERBOSE == TRUE) */
1474
1475
1476