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