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