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_NO_SERVICE );
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 /* if SN type is included without SN */
659 if (params.sn[1] == LLCP_SN_TYPE)
660 {
661 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
662 }
663 else
664 {
665 /* SDP doesn't accept connection */
666 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
667 }
668 return;
669 }
670
671 if (dsap == LLCP_SAP_SDP)
672 {
673 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): SDP doesn't accept connection");
674
675 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
676 return;
677 }
678 else if (dsap == 0)
679 {
680 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered Service:%s", params.sn);
681
682 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
683 return;
684 }
685 else
686 {
687 /* check if this application can support connection-oriented transport */
688 p_app_cb = llcp_util_get_app_cb (dsap);
689
690 if ( (p_app_cb == NULL)
691 ||(p_app_cb->p_app_cback == NULL)
692 ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0) )
693 {
694 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): SAP(0x%x) doesn't support connection-oriented", dsap);
695 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
696 return;
697 }
698 }
699 }
700
701 /* check if any data link */
702 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
703 if (p_dlcb)
704 {
705 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Data link is aleady established");
706 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
707 }
708 else
709 {
710 /* allocate data link connection control block and notify upper layer through state machine */
711 p_dlcb = llcp_util_allocate_data_link (dsap, ssap);
712
713 if (p_dlcb)
714 {
715 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, ¶ms);
716 if (status != LLCP_STATUS_SUCCESS)
717 {
718 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Error in state machine");
719 llcp_util_deallocate_data_link (p_dlcb);
720 }
721 }
722 else
723 {
724 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Out of resource");
725 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY );
726 }
727 }
728 }
729
730 /*******************************************************************************
731 **
732 ** Function llcp_dlc_proc_disc_pdu
733 **
734 ** Description Process DISC PDU
735 **
736 ** Returns void
737 **
738 *******************************************************************************/
llcp_dlc_proc_disc_pdu(UINT8 dsap,UINT8 ssap,UINT16 length,UINT8 * p_data)739 static void llcp_dlc_proc_disc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
740 {
741 tLLCP_DLCB *p_dlcb;
742
743 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_disc_pdu ()");
744
745 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
746 if (p_dlcb)
747 {
748 if (length > 0)
749 {
750 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC PDU", length);
751
752 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
753 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
754 }
755 else
756 {
757 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
758 }
759 }
760 else
761 {
762 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
763 }
764 }
765
766 /*******************************************************************************
767 **
768 ** Function llcp_dlc_proc_cc_pdu
769 **
770 ** Description Process CC PDU
771 **
772 ** Returns void
773 **
774 *******************************************************************************/
llcp_dlc_proc_cc_pdu(UINT8 dsap,UINT8 ssap,UINT16 length,UINT8 * p_data)775 static void llcp_dlc_proc_cc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
776 {
777 tLLCP_DLCB *p_dlcb;
778 tLLCP_CONNECTION_PARAMS params;
779 tLLCP_STATUS status;
780
781 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_cc_pdu ()");
782
783 /* find a DLCB waiting for CC on this local SAP */
784 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
785 if (p_dlcb)
786 {
787 /* The CC may contain a SSAP that is different from the DSAP in the CONNECT */
788 p_dlcb->remote_sap = ssap;
789
790 if (llcp_util_parse_cc (p_data, length, &(params.miu), &(params.rw)) == LLCP_STATUS_SUCCESS)
791 {
792 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, ¶ms);
793 if (status != LLCP_STATUS_SUCCESS)
794 {
795 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_cc_pdu (): Error in state machine");
796 llcp_util_deallocate_data_link (p_dlcb);
797 }
798 }
799 else
800 {
801 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
802 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
803 }
804 }
805 else
806 {
807 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
808 }
809 }
810
811 /*******************************************************************************
812 **
813 ** Function llcp_dlc_proc_dm_pdu
814 **
815 ** Description Process DM PDU
816 **
817 ** Returns void
818 **
819 *******************************************************************************/
llcp_dlc_proc_dm_pdu(UINT8 dsap,UINT8 ssap,UINT16 length,UINT8 * p_data)820 static void llcp_dlc_proc_dm_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
821 {
822 tLLCP_DLCB *p_dlcb;
823
824 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_dm_pdu ()");
825
826 if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE)
827 {
828 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
829 }
830 else
831 {
832 if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC)
833 {
834 /* local device initiated disconnecting */
835 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
836 }
837 else
838 {
839 /* peer device rejected connection with any reason */
840 /* find a DLCB waiting for CC on this local SAP */
841 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
842 }
843
844 if (p_dlcb)
845 {
846 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, p_data); /* passing reason */
847 }
848 else
849 {
850 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
851 }
852 }
853 }
854
855 /*******************************************************************************
856 **
857 ** Function llcp_dlc_proc_i_pdu
858 **
859 ** Description Process I PDU
860 **
861 ** Returns void
862 **
863 *******************************************************************************/
llcp_dlc_proc_i_pdu(UINT8 dsap,UINT8 ssap,UINT16 i_pdu_length,UINT8 * p_i_pdu,BT_HDR * p_msg)864 void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg)
865 {
866 UINT8 *p, *p_dst, send_seq, rcv_seq, error_flags;
867 UINT16 info_len, available_bytes;
868 tLLCP_DLCB *p_dlcb;
869 BOOLEAN appended;
870 BT_HDR *p_last_buf;
871
872 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_i_pdu ()");
873
874 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
875
876 if ((p_dlcb)&&(p_dlcb->state == LLCP_DLC_STATE_CONNECTED))
877 {
878 error_flags = 0;
879
880 if (p_msg)
881 {
882 i_pdu_length = p_msg->len;
883 p_i_pdu = (UINT8 *) (p_msg + 1) + p_msg->offset;
884 }
885
886 info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
887
888 if (info_len > p_dlcb->local_miu)
889 {
890 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d bytes SDU",
891 p_dlcb->local_miu, info_len);
892
893 error_flags |= LLCP_FRMR_I_ERROR_FLAG;
894 }
895
896 /* get sequence numbers */
897 p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
898
899 send_seq = LLCP_GET_NS (*p);
900 rcv_seq = LLCP_GET_NR (*p);
901
902 #if (BT_TRACE_VERBOSE == TRUE)
903 LLCP_TRACE_DEBUG6 ("LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
904 send_seq, rcv_seq,
905 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
906 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
907 #endif
908
909 /* if send sequence number, N(S) is not expected one, V(R) */
910 if (p_dlcb->next_rx_seq != send_seq)
911 {
912 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
913 send_seq, p_dlcb->next_rx_seq);
914
915 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
916 }
917 else
918 {
919 /* if peer device sends more than our receiving window size */
920 if ((UINT8) (send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >= p_dlcb->local_rw)
921 {
922 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
923 send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
924
925 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
926 }
927 }
928
929 /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
930 if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
931 != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO)
932 {
933 error_flags |= LLCP_FRMR_R_ERROR_FLAG;
934 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
935 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
936 }
937
938 /* if any error is found */
939 if (error_flags)
940 {
941 llcp_util_send_frmr (p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
942 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
943 }
944 else
945 {
946 /* update local sequence variables */
947 p_dlcb->next_rx_seq = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
948 p_dlcb->rcvd_ack_seq = rcv_seq;
949
950 appended = FALSE;
951
952 /* get last buffer in rx queue */
953 p_last_buf = (BT_HDR *) GKI_getlast (&p_dlcb->i_rx_q);
954
955 if (p_last_buf)
956 {
957 /* get max length to append at the end of buffer */
958 available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
959
960 /* if new UI PDU with length can be attached at the end of buffer */
961 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len)
962 {
963 p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
964
965 /* add length of information in I PDU */
966 UINT16_TO_BE_STREAM (p_dst, info_len);
967
968 /* copy information of I PDU */
969 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
970
971 memcpy (p_dst, p, info_len);
972
973 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
974
975 if (p_msg)
976 {
977 GKI_freebuf (p_msg);
978 p_msg = NULL;
979 }
980
981 appended = TRUE;
982 }
983 }
984
985 /* if it is not available to append */
986 if (!appended)
987 {
988 /* if it's not from AGF PDU */
989 if (p_msg)
990 {
991 /* add length of information in front of information */
992 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
993 UINT16_TO_BE_STREAM (p, info_len);
994
995 p_msg->offset += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
996 p_msg->len -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
997 p_msg->layer_specific = 0;
998 }
999 else
1000 {
1001 p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
1002
1003 if (p_msg)
1004 {
1005 p_dst = (UINT8*) (p_msg + 1);
1006
1007 /* add length of information in front of information */
1008 UINT16_TO_BE_STREAM (p_dst, info_len);
1009
1010 p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
1011 memcpy (p_dst, p, info_len);
1012
1013 p_msg->offset = 0;
1014 p_msg->len = LLCP_PDU_AGF_LEN_SIZE + info_len;
1015 p_msg->layer_specific = 0;
1016 }
1017 else
1018 {
1019 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_i_pdu (): out of buffer");
1020 }
1021 }
1022
1023 /* insert I PDU in rx queue */
1024 if (p_msg)
1025 {
1026 GKI_enqueue (&p_dlcb->i_rx_q, p_msg);
1027 p_msg = NULL;
1028 llcp_cb.total_rx_i_pdu++;
1029
1030 llcp_util_check_rx_congested_status ();
1031 }
1032 }
1033
1034 p_dlcb->num_rx_i_pdu++;
1035
1036 if ( (!p_dlcb->local_busy)
1037 &&(p_dlcb->num_rx_i_pdu == 1) )
1038 {
1039 /* notify rx data is available so upper layer reads data until queue is empty */
1040 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1041 }
1042
1043 if ( (!p_dlcb->is_rx_congested)
1044 &&(p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold) )
1045 {
1046 LLCP_TRACE_DEBUG2 ("llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, rx_congest_threshold=%d",
1047 p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
1048
1049 /* send RNR */
1050 p_dlcb->is_rx_congested = TRUE;
1051 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1052 }
1053 }
1054 }
1055 else
1056 {
1057 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
1058 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION );
1059 }
1060
1061 if (p_msg)
1062 {
1063 GKI_freebuf (p_msg);
1064 }
1065 }
1066
1067 /*******************************************************************************
1068 **
1069 ** Function llcp_dlc_proc_rr_rnr_pdu
1070 **
1071 ** Description Process RR or RNR PDU
1072 **
1073 ** Returns void
1074 **
1075 *******************************************************************************/
llcp_dlc_proc_rr_rnr_pdu(UINT8 dsap,UINT8 ptype,UINT8 ssap,UINT16 length,UINT8 * p_data)1076 static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1077 {
1078 UINT8 rcv_seq, error_flags;
1079 tLLCP_DLCB *p_dlcb;
1080 BOOLEAN flush = TRUE;
1081 tLLCP_SAP_CBACK_DATA cback_data;
1082 BOOLEAN old_remote_busy;
1083
1084 LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
1085
1086 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1087 if (p_dlcb != NULL)
1088 {
1089 error_flags = 0;
1090
1091 rcv_seq = LLCP_GET_NR (*p_data);
1092
1093 if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE)
1094 {
1095 error_flags |= LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG;
1096 }
1097
1098 /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
1099 if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
1100 != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
1101 {
1102 error_flags |= LLCP_FRMR_R_ERROR_FLAG;
1103 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
1104 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
1105 }
1106
1107 if (error_flags)
1108 {
1109 llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
1110 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1111 }
1112 else
1113 {
1114 p_dlcb->rcvd_ack_seq = rcv_seq;
1115
1116 #if (BT_TRACE_VERBOSE == TRUE)
1117 LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1118 rcv_seq,
1119 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1120 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1121 #endif
1122 old_remote_busy = p_dlcb->remote_busy;
1123 if (ptype == LLCP_PDU_RNR_TYPE)
1124 {
1125 p_dlcb->remote_busy = TRUE;
1126 /* if upper layer hasn't get congestion started notification */
1127 if ( (!old_remote_busy)
1128 &&(!p_dlcb->is_tx_congested) )
1129 {
1130 LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
1131 p_dlcb->local_sap, p_dlcb->remote_sap,
1132 p_dlcb->i_xmit_q.count);
1133
1134 cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1135 cback_data.congest.local_sap = p_dlcb->local_sap;
1136 cback_data.congest.remote_sap = p_dlcb->remote_sap;
1137 cback_data.congest.is_congested = TRUE;
1138 cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1139
1140 (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1141 }
1142 }
1143 else
1144 {
1145 p_dlcb->remote_busy = FALSE;
1146 /* if upper layer hasn't get congestion ended notification and data link is not congested */
1147 if ( (old_remote_busy)
1148 &&(!p_dlcb->is_tx_congested) )
1149 {
1150 LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
1151 p_dlcb->local_sap, p_dlcb->remote_sap,
1152 p_dlcb->i_xmit_q.count);
1153
1154 cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1155 cback_data.congest.local_sap = p_dlcb->local_sap;
1156 cback_data.congest.remote_sap = p_dlcb->remote_sap;
1157 cback_data.congest.is_congested = FALSE;
1158 cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1159
1160 (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1161 }
1162 }
1163
1164 /* check flag to send DISC when tx queue is empty */
1165 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1166 {
1167 /* if no pending data and all PDU is acked */
1168 if ( (p_dlcb->i_xmit_q.count == 0)
1169 &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1170 &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq) )
1171 {
1172 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1173 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1174 }
1175 }
1176 }
1177 }
1178 else
1179 {
1180 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
1181 }
1182 }
1183
1184 /*******************************************************************************
1185 **
1186 ** Function llcp_dlc_proc_rx_pdu
1187 **
1188 ** Description Process PDU for data link
1189 **
1190 ** Returns void
1191 **
1192 *******************************************************************************/
llcp_dlc_proc_rx_pdu(UINT8 dsap,UINT8 ptype,UINT8 ssap,UINT16 length,UINT8 * p_data)1193 void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1194 {
1195 tLLCP_DLCB *p_dlcb;
1196
1197 LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
1198 dsap, ptype, ssap);
1199
1200 if (dsap == LLCP_SAP_LM)
1201 {
1202 LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
1203 return;
1204 }
1205
1206 switch (ptype)
1207 {
1208 case LLCP_PDU_CONNECT_TYPE:
1209 llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
1210 break;
1211
1212 case LLCP_PDU_DISC_TYPE:
1213 llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
1214 break;
1215
1216 case LLCP_PDU_CC_TYPE:
1217 llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
1218 break;
1219
1220 case LLCP_PDU_DM_TYPE:
1221 llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
1222 break;
1223
1224 case LLCP_PDU_FRMR_TYPE:
1225 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1226 if (p_dlcb)
1227 {
1228 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1229 }
1230 break;
1231
1232 case LLCP_PDU_RR_TYPE:
1233 case LLCP_PDU_RNR_TYPE:
1234 llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
1235 break;
1236
1237 default:
1238 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
1239
1240 p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1241 if (p_dlcb)
1242 {
1243 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
1244 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1245 }
1246 break;
1247 }
1248 }
1249
1250 /*******************************************************************************
1251 **
1252 ** Function llcp_dlc_check_to_send_rr_rnr
1253 **
1254 ** Description Send RR or RNR if necessary
1255 **
1256 ** Returns void
1257 **
1258 *******************************************************************************/
llcp_dlc_check_to_send_rr_rnr(void)1259 void llcp_dlc_check_to_send_rr_rnr (void)
1260 {
1261 UINT8 idx;
1262 BOOLEAN flush = TRUE;
1263
1264 LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
1265
1266 /*
1267 ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
1268 ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
1269 ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
1270 **
1271 ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
1272 ** V(R).
1273 */
1274 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
1275 {
1276 if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
1277 {
1278 llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
1279
1280 /* check flag to send DISC when tx queue is empty */
1281 if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1282 {
1283 /* if no pending data and all PDU is acked */
1284 if ( (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
1285 &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
1286 &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq) )
1287 {
1288 llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1289 llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1290 }
1291 }
1292 }
1293 }
1294 }
1295
1296 /*******************************************************************************
1297 **
1298 ** Function llcp_dlc_is_rw_open
1299 **
1300 ** Description check if receive window is open in remote
1301 **
1302 ** Returns TRUE if remote can receive more data
1303 **
1304 *******************************************************************************/
llcp_dlc_is_rw_open(tLLCP_DLCB * p_dlcb)1305 BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
1306 {
1307 if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
1308 {
1309 return TRUE;
1310 }
1311 else
1312 {
1313 LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
1314 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
1315 return FALSE;
1316 }
1317 }
1318
1319 /*******************************************************************************
1320 **
1321 ** Function llcp_dlc_get_next_pdu
1322 **
1323 ** Description Get a PDU from tx queue of data link
1324 **
1325 ** Returns BT_HDR*
1326 **
1327 *******************************************************************************/
llcp_dlc_get_next_pdu(tLLCP_DLCB * p_dlcb)1328 BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
1329 {
1330 BT_HDR *p_msg = NULL;
1331 BOOLEAN flush = TRUE;
1332 tLLCP_SAP_CBACK_DATA data;
1333
1334 #if (BT_TRACE_VERBOSE == TRUE)
1335 UINT8 send_seq = p_dlcb->next_tx_seq;
1336 #endif
1337
1338 /* if there is data to send and remote device can receive it */
1339 if ( (p_dlcb->i_xmit_q.count)
1340 &&(!p_dlcb->remote_busy)
1341 &&(llcp_dlc_is_rw_open (p_dlcb)) )
1342 {
1343 p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
1344 llcp_cb.total_tx_i_pdu--;
1345
1346 if (p_msg->offset >= LLCP_MIN_OFFSET)
1347 {
1348 /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
1349 llcp_util_build_info_pdu (p_dlcb, p_msg);
1350
1351 p_dlcb->next_tx_seq = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
1352
1353 #if (BT_TRACE_VERBOSE == TRUE)
1354 LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1355 send_seq, p_dlcb->next_rx_seq,
1356 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1357 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1358 #endif
1359 }
1360 else
1361 {
1362 LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
1363 p_msg->offset, LLCP_MIN_OFFSET );
1364 GKI_freebuf (p_msg);
1365 p_msg = NULL;
1366 }
1367 }
1368
1369 /* if tx queue is empty and all PDU is acknowledged */
1370 if ( (p_dlcb->i_xmit_q.count == 0)
1371 &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1372 &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq) )
1373 {
1374 /* check flag to send DISC */
1375 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1376 {
1377 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1378 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1379 }
1380
1381 /* check flag to notify upper layer */
1382 if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
1383 {
1384 p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1385
1386 data.tx_complete.event = LLCP_SAP_EVT_TX_COMPLETE;
1387 data.tx_complete.local_sap = p_dlcb->local_sap;
1388 data.tx_complete.remote_sap = p_dlcb->remote_sap;
1389
1390 (*p_dlcb->p_app_cb->p_app_cback) (&data);
1391 }
1392 }
1393
1394 return p_msg;
1395 }
1396
1397 /*******************************************************************************
1398 **
1399 ** Function llcp_dlc_get_next_pdu_length
1400 **
1401 ** Description return length of PDU which is top in tx queue of data link
1402 **
1403 ** Returns length of PDU
1404 **
1405 *******************************************************************************/
llcp_dlc_get_next_pdu_length(tLLCP_DLCB * p_dlcb)1406 UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
1407 {
1408 BT_HDR *p_msg;
1409
1410 /* if there is data to send and remote device can receive it */
1411 if ( (p_dlcb->i_xmit_q.count)
1412 &&(!p_dlcb->remote_busy)
1413 &&(llcp_dlc_is_rw_open (p_dlcb)) )
1414 {
1415 p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
1416
1417 return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
1418 }
1419 return 0;
1420 }
1421
1422 #if (BT_TRACE_VERBOSE == TRUE)
1423 /*******************************************************************************
1424 **
1425 ** Function llcp_dlsm_get_state_name
1426 **
1427 ** Description This function returns the state name.
1428 **
1429 ** Returns pointer to the name
1430 **
1431 *******************************************************************************/
llcp_dlsm_get_state_name(tLLCP_DLC_STATE state)1432 static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
1433 {
1434 switch (state)
1435 {
1436 case LLCP_DLC_STATE_IDLE:
1437 return ("IDLE");
1438 case LLCP_DLC_STATE_W4_REMOTE_RESP:
1439 return ("W4_REMOTE_RESP");
1440 case LLCP_DLC_STATE_W4_LOCAL_RESP:
1441 return ("W4_LOCAL_RESP");
1442 case LLCP_DLC_STATE_CONNECTED:
1443 return ("CONNECTED");
1444 case LLCP_DLC_STATE_W4_REMOTE_DM:
1445 return ("W4_REMOTE_DM");
1446 default:
1447 return ("???? UNKNOWN STATE");
1448 }
1449 }
1450
1451 /*******************************************************************************
1452 **
1453 ** Function llcp_dlsm_get_event_name
1454 **
1455 ** Description This function returns the event name.
1456 **
1457 ** Returns pointer to the name
1458 **
1459 *******************************************************************************/
llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event)1460 static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
1461 {
1462 switch (event)
1463 {
1464 case LLCP_DLC_EVENT_API_CONNECT_REQ:
1465 return ("API_CONNECT_REQ");
1466 case LLCP_DLC_EVENT_API_CONNECT_CFM:
1467 return ("API_CONNECT_CFM");
1468 case LLCP_DLC_EVENT_API_CONNECT_REJECT:
1469 return ("API_CONNECT_REJECT");
1470 case LLCP_DLC_EVENT_PEER_CONNECT_IND:
1471 return ("PEER_CONNECT_IND");
1472 case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
1473 return ("PEER_CONNECT_CFM");
1474
1475 case LLCP_DLC_EVENT_API_DATA_REQ:
1476 return ("API_DATA_REQ");
1477 case LLCP_DLC_EVENT_PEER_DATA_IND:
1478 return ("PEER_DATA_IND");
1479
1480 case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
1481 return ("API_DISCONNECT_REQ");
1482 case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
1483 return ("PEER_DISCONNECT_IND");
1484 case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
1485 return ("PEER_DISCONNECT_RESP");
1486
1487 case LLCP_DLC_EVENT_FRAME_ERROR:
1488 return ("FRAME_ERROR");
1489 case LLCP_DLC_EVENT_LINK_ERROR:
1490 return ("LINK_ERROR");
1491
1492 case LLCP_DLC_EVENT_TIMEOUT:
1493 return ("TIMEOUT");
1494
1495 default:
1496 return ("???? UNKNOWN EVENT");
1497 }
1498 }
1499 #endif /* (BT_TRACE_VERBOSE == TRUE) */
1500
1501
1502