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