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