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