llcp_api.c revision 5c65c3a0f42e174e47fecd4e569606003217ff4e
1/******************************************************************************
2 *
3 *  Copyright (C) 2010-2013 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19
20/******************************************************************************
21 *
22 *  This file contains the LLCP API code
23 *
24 ******************************************************************************/
25
26#include <string.h>
27#include "gki.h"
28#include "nfc_target.h"
29#include "bt_types.h"
30#include "llcp_api.h"
31#include "llcp_int.h"
32#include "llcp_defs.h"
33
34#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
35
36tLLCP_TEST_PARAMS llcp_test_params =
37{
38    LLCP_VERSION_VALUE,
39    0,                             /* not override */
40};
41
42/*******************************************************************************
43**
44** Function         LLCP_SetTestParams
45**
46** Description      Set test parameters for LLCP
47**
48**
49** Returns          void
50**
51*******************************************************************************/
52void LLCP_SetTestParams (UINT8 version, UINT16 wks)
53{
54    LLCP_TRACE_API2 ("LLCP_SetTestParams () version:0x%02X, wks:0x%04X",
55                     version, wks);
56
57    if (version != 0xFF)
58        llcp_test_params.version = version;
59
60    if (wks != 0xFFFF)
61        llcp_test_params.wks = wks;
62}
63#endif
64
65/*******************************************************************************
66**
67** Function         LLCP_RegisterDtaCback
68**
69** Description      Register callback function for LLCP DTA testing
70**
71**
72** Returns          void
73**
74*******************************************************************************/
75void LLCP_RegisterDtaCback (tLLCP_DTA_CBACK *p_dta_cback)
76{
77    LLCP_TRACE_API0 ("LLCP_RegisterDtaCback ()");
78
79    llcp_cb.p_dta_cback = p_dta_cback;
80}
81
82/*******************************************************************************
83**
84** Function         LLCP_SetConfig
85**
86** Description      Set configuration parameters for LLCP
87**                  - Local Link MIU
88**                  - Option parameter
89**                  - Response Waiting Time Index
90**                  - Local Link Timeout
91**                  - Inactivity Timeout as initiator role
92**                  - Inactivity Timeout as target role
93**                  - Delay SYMM response
94**                  - Data link connection timeout
95**                  - Delay timeout to send first PDU as initiator
96**
97** Returns          void
98**
99*******************************************************************************/
100void LLCP_SetConfig (UINT16 link_miu,
101                     UINT8  opt,
102                     UINT8  wt,
103                     UINT16 link_timeout,
104                     UINT16 inact_timeout_init,
105                     UINT16 inact_timeout_target,
106                     UINT16 symm_delay,
107                     UINT16 data_link_timeout,
108                     UINT16 delay_first_pdu_timeout)
109{
110    LLCP_TRACE_API4 ("LLCP_SetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
111                     link_miu, opt, wt, link_timeout);
112    LLCP_TRACE_API4 ("                 inact_timeout (init:%d,target:%d), symm_delay:%d, data_link_timeout:%d",
113                     inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
114    LLCP_TRACE_API1 ("                 delay_first_pdu_timeout:%d", delay_first_pdu_timeout);
115
116    if (link_miu < LLCP_DEFAULT_MIU)
117    {
118        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be smaller than LLCP_DEFAULT_MIU (%d)",
119                            LLCP_DEFAULT_MIU);
120        link_miu = LLCP_DEFAULT_MIU;
121    }
122    else if (link_miu > LLCP_MAX_MIU)
123    {
124        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MAX_MIU (%d)",
125                            LLCP_MAX_MIU);
126        link_miu = LLCP_MAX_MIU;
127    }
128
129    /* if Link MIU is bigger than GKI buffer */
130    if (link_miu > LLCP_MIU)
131    {
132        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MIU (%d)",
133                            LLCP_MIU);
134        llcp_cb.lcb.local_link_miu = LLCP_MIU;
135    }
136    else
137        llcp_cb.lcb.local_link_miu = link_miu;
138
139    llcp_cb.lcb.local_opt = opt;
140    llcp_cb.lcb.local_wt  = wt;
141
142    if (link_timeout < LLCP_LTO_UNIT)
143    {
144        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be smaller than LLCP_LTO_UNIT (%d ms)",
145                            LLCP_LTO_UNIT);
146        llcp_cb.lcb.local_lto = LLCP_DEFAULT_LTO_IN_MS;
147    }
148    else if (link_timeout > LLCP_MAX_LTO_IN_MS)
149    {
150        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be bigger than LLCP_MAX_LTO_IN_MS (%d ms)",
151                            LLCP_MAX_LTO_IN_MS);
152        llcp_cb.lcb.local_lto = LLCP_MAX_LTO_IN_MS;
153    }
154    else
155        llcp_cb.lcb.local_lto = link_timeout;
156
157    llcp_cb.lcb.inact_timeout_init   = inact_timeout_init;
158    llcp_cb.lcb.inact_timeout_target = inact_timeout_target;
159    llcp_cb.lcb.symm_delay           = symm_delay;
160    llcp_cb.lcb.data_link_timeout    = data_link_timeout;
161    llcp_cb.lcb.delay_first_pdu_timeout = delay_first_pdu_timeout;
162}
163
164/*******************************************************************************
165**
166** Function         LLCP_GetConfig
167**
168** Description      Get configuration parameters for LLCP
169**                  - Local Link MIU
170**                  - Option parameter
171**                  - Response Waiting Time Index
172**                  - Local Link Timeout
173**                  - Inactivity Timeout as initiator role
174**                  - Inactivity Timeout as target role
175**                  - Delay SYMM response
176**                  - Data link connection timeout
177**                  - Delay timeout to send first PDU as initiator
178**
179** Returns          void
180**
181*******************************************************************************/
182void LLCP_GetConfig (UINT16 *p_link_miu,
183                     UINT8  *p_opt,
184                     UINT8  *p_wt,
185                     UINT16 *p_link_timeout,
186                     UINT16 *p_inact_timeout_init,
187                     UINT16 *p_inact_timeout_target,
188                     UINT16 *p_symm_delay,
189                     UINT16 *p_data_link_timeout,
190                     UINT16 *p_delay_first_pdu_timeout)
191{
192    *p_link_miu             = llcp_cb.lcb.local_link_miu;
193    *p_opt                  = llcp_cb.lcb.local_opt;
194    *p_wt                   = llcp_cb.lcb.local_wt;
195    *p_link_timeout         = llcp_cb.lcb.local_lto;
196    *p_inact_timeout_init   = llcp_cb.lcb.inact_timeout_init;
197    *p_inact_timeout_target = llcp_cb.lcb.inact_timeout_target;
198    *p_symm_delay           = llcp_cb.lcb.symm_delay;
199    *p_data_link_timeout    = llcp_cb.lcb.data_link_timeout;
200    *p_delay_first_pdu_timeout = llcp_cb.lcb.delay_first_pdu_timeout;
201
202    LLCP_TRACE_API4 ("LLCP_GetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
203                     *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
204    LLCP_TRACE_API4 ("                 inact_timeout (init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
205                     *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, *p_data_link_timeout);
206    LLCP_TRACE_API1 ("                 delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout);
207}
208
209/*******************************************************************************
210**
211** Function         LLCP_GetDiscoveryConfig
212**
213** Description      Returns discovery config for ISO 18092 MAC link activation
214**                  This function is called to get general bytes for NFC_PMID_ATR_REQ_GEN_BYTES
215**                  or NFC_PMID_ATR_RES_GEN_BYTES before starting discovery.
216**
217**                  wt:Waiting time 0 - 8, only for listen
218**                  p_gen_bytes: pointer to store LLCP magic number and paramters
219**                  p_gen_bytes_len: length of buffer for gen bytes as input
220**                                   (NOTE:it must be bigger than LLCP_MIN_GEN_BYTES)
221**                                   actual gen bytes size as output
222**
223**                  Restrictions on the use of ISO 18092
224**                  1. The DID features shall not be used.
225**                  2. the NAD features shall not be used.
226**                  3. Frame waiting time extentions (WTX) shall not be used.
227**
228** Returns          None
229**
230*******************************************************************************/
231void LLCP_GetDiscoveryConfig (UINT8 *p_wt,
232                              UINT8 *p_gen_bytes,
233                              UINT8 *p_gen_bytes_len)
234{
235    UINT8      *p = p_gen_bytes;
236
237    LLCP_TRACE_API0 ("LLCP_GetDiscoveryConfig ()");
238
239    if (*p_gen_bytes_len < LLCP_MIN_GEN_BYTES)
240    {
241        LLCP_TRACE_ERROR1 ("LLCP_GetDiscoveryConfig (): GenBytes length shall not be smaller than LLCP_MIN_GEN_BYTES (%d)",
242                            LLCP_MIN_GEN_BYTES);
243        *p_gen_bytes_len = 0;
244        return;
245    }
246
247    *p_wt = llcp_cb.lcb.local_wt;
248
249    UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE0);
250    UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE1);
251    UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE2);
252
253#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
254    UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
255    UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
256    UINT8_TO_BE_STREAM (p, llcp_test_params.version);
257
258    UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
259    UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
260    UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
261
262    UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
263    UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
264    if (llcp_test_params.wks == 0)  /* not override */
265    {
266        UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
267    }
268    else
269    {
270        UINT16_TO_BE_STREAM (p, llcp_test_params.wks);
271    }
272#else
273    UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
274    UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
275    UINT8_TO_BE_STREAM (p, LLCP_VERSION_VALUE);
276
277    UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
278    UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
279    UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
280
281    UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
282    UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
283    UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
284#endif
285
286    UINT8_TO_BE_STREAM (p, LLCP_LTO_TYPE);
287    UINT8_TO_BE_STREAM (p, LLCP_LTO_LEN);
288    UINT8_TO_BE_STREAM (p, (llcp_cb.lcb.local_lto/LLCP_LTO_UNIT));
289
290    UINT8_TO_BE_STREAM (p, LLCP_OPT_TYPE);
291    UINT8_TO_BE_STREAM (p, LLCP_OPT_LEN);
292    UINT8_TO_BE_STREAM (p, llcp_cb.lcb.local_opt);
293
294    *p_gen_bytes_len = (UINT8) (p - p_gen_bytes);
295}
296
297/*******************************************************************************
298**
299** Function         LLCP_ActivateLink
300**
301** Description      This function will activate LLCP link with LR, WT and Gen Bytes
302**                  in activation NTF from NFCC.
303**
304**                  LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
305**                  callback function if successful.
306**                  Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
307**
308** Returns          LLCP_STATUS_SUCCESS if success
309**
310*******************************************************************************/
311tLLCP_STATUS LLCP_ActivateLink (tLLCP_ACTIVATE_CONFIG config,
312                                tLLCP_LINK_CBACK     *p_link_cback)
313{
314    LLCP_TRACE_API1 ("LLCP_ActivateLink () link_state = %d", llcp_cb.lcb.link_state);
315
316    if (  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
317        &&(p_link_cback)  )
318    {
319        llcp_cb.lcb.p_link_cback = p_link_cback;
320        return (llcp_link_activate (&config));
321    }
322    else
323        return LLCP_STATUS_FAIL;
324}
325
326/*******************************************************************************
327**
328** Function         LLCP_DeactivateLink
329**
330** Description      Deactivate LLCP link
331**
332**                  LLCP_LINK_DEACTIVATED_EVT will be returned through callback
333**                  when LLCP link is deactivated. Then NFC link may be deactivated.
334**
335** Returns          LLCP_STATUS_SUCCESS if success
336**
337*******************************************************************************/
338tLLCP_STATUS LLCP_DeactivateLink (void)
339{
340    LLCP_TRACE_API1 ("LLCP_DeactivateLink () link_state = %d", llcp_cb.lcb.link_state);
341
342    if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
343    {
344        llcp_link_deactivate (LLCP_LINK_LOCAL_INITIATED);
345        return LLCP_STATUS_SUCCESS;
346    }
347    else
348        return LLCP_STATUS_FAIL;
349}
350
351/*******************************************************************************
352**
353** Function         LLCP_RegisterServer
354**
355** Description      Register server and callback function
356**
357**                  reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
358**                            Advertized by SDP (0x10 - 0x1F)
359**                            LLCP_INVALID_SAP, LLCP will allocate between 0x10 and 0x1F
360**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
361**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
362**                  p_service_name : Null-terminated string up to LLCP_MAX_SN_LEN
363**
364** Returns          SAP between 0x02 and 0x1F, if success
365**                  LLCP_INVALID_SAP, otherwise
366**
367*******************************************************************************/
368UINT8 LLCP_RegisterServer (UINT8           reg_sap,
369                           UINT8           link_type,
370                           char            *p_service_name,
371                           tLLCP_APP_CBACK *p_app_cback)
372{
373    UINT8  sap;
374    UINT16 length;
375    tLLCP_APP_CB *p_app_cb;
376
377    LLCP_TRACE_API3 ("LLCP_RegisterServer (): SAP:0x%x, link_type:0x%x, ServiceName:<%s>",
378                     reg_sap, link_type, ((p_service_name == NULL) ? "" : p_service_name));
379
380    if (!p_app_cback)
381    {
382        LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Callback must be provided");
383        return LLCP_INVALID_SAP;
384    }
385    else if (  ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
386             &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)  )
387    {
388        LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): link type (0x%x) must be specified", link_type);
389        return LLCP_INVALID_SAP;
390    }
391
392    if (reg_sap == LLCP_INVALID_SAP)
393    {
394        /* allocate a SAP between 0x10 and 0x1F */
395        for (sap = 0; sap < LLCP_MAX_SERVER; sap++)
396        {
397            if (llcp_cb.server_cb[sap].p_app_cback == NULL)
398            {
399                p_app_cb = &llcp_cb.server_cb[sap];
400                reg_sap  = LLCP_LOWER_BOUND_SDP_SAP + sap;
401                break;
402            }
403        }
404
405        if (reg_sap == LLCP_INVALID_SAP)
406        {
407            LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): out of resource");
408            return LLCP_INVALID_SAP;
409        }
410    }
411    else if (reg_sap == LLCP_SAP_LM)
412    {
413        LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is for link manager", reg_sap);
414        return LLCP_INVALID_SAP;
415    }
416    else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
417    {
418        if (reg_sap >= LLCP_MAX_WKS)
419        {
420            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
421            return LLCP_INVALID_SAP;
422        }
423        else if (llcp_cb.wks_cb[reg_sap].p_app_cback)
424        {
425            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
426            return LLCP_INVALID_SAP;
427        }
428        else
429        {
430            p_app_cb = &llcp_cb.wks_cb[reg_sap];
431        }
432    }
433    else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP)
434    {
435        if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER)
436        {
437            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
438            return LLCP_INVALID_SAP;
439        }
440        else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP].p_app_cback)
441        {
442            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
443            return LLCP_INVALID_SAP;
444        }
445        else
446        {
447            p_app_cb = &llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP];
448        }
449    }
450    else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP)
451    {
452        LLCP_TRACE_ERROR2 ("LLCP_RegisterServer (): SAP (0x%x) must be less than 0x%x",
453                            reg_sap, LLCP_LOWER_BOUND_LOCAL_SAP);
454        return LLCP_INVALID_SAP;
455    }
456
457    memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
458
459    if (p_service_name)
460    {
461        length = (UINT8) strlen (p_service_name);
462        if (length > LLCP_MAX_SN_LEN)
463        {
464            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): Service Name (%d bytes) is too long", length);
465            return LLCP_INVALID_SAP;
466        }
467
468        p_app_cb->p_service_name = (UINT8 *) GKI_getbuf ((UINT16) (length + 1));
469        if (p_app_cb->p_service_name == NULL)
470        {
471            LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Out of resource");
472            return LLCP_INVALID_SAP;
473        }
474
475        BCM_STRNCPY_S ((char *) p_app_cb->p_service_name, length + 1, (char *) p_service_name, length + 1);
476        p_app_cb->p_service_name[length] = 0;
477    }
478    else
479        p_app_cb->p_service_name = NULL;
480
481    p_app_cb->p_app_cback = p_app_cback;
482    p_app_cb->link_type   = link_type;
483
484    if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
485    {
486        llcp_cb.lcb.wks |= (1 << reg_sap);
487    }
488
489    LLCP_TRACE_DEBUG1 ("LLCP_RegisterServer (): Registered SAP = 0x%02X", reg_sap);
490
491    if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
492    {
493        llcp_cb.num_logical_data_link++;
494        llcp_util_adjust_ll_congestion ();
495    }
496
497    return reg_sap;
498}
499
500/*******************************************************************************
501**
502** Function         LLCP_RegisterClient
503**
504** Description      Register client and callback function
505**
506**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
507**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
508**
509** Returns          SAP between 0x20 and 0x3F, if success
510**                  LLCP_INVALID_SAP, otherwise
511**
512*******************************************************************************/
513UINT8 LLCP_RegisterClient (UINT8           link_type,
514                           tLLCP_APP_CBACK *p_app_cback)
515{
516    UINT8 reg_sap = LLCP_INVALID_SAP;
517    UINT8 sap;
518    tLLCP_APP_CB *p_app_cb;
519
520    LLCP_TRACE_API1 ("LLCP_RegisterClient (): link_type = 0x%x", link_type);
521
522    if (!p_app_cback)
523    {
524        LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): Callback must be provided");
525        return LLCP_INVALID_SAP;
526    }
527    else if (  ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
528             &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)  )
529    {
530        LLCP_TRACE_ERROR1 ("LLCP_RegisterClient (): link type (0x%x) must be specified", link_type);
531        return LLCP_INVALID_SAP;
532    }
533
534    /* allocate a SAP between 0x20 and 0x3F */
535    for (sap = 0; sap < LLCP_MAX_CLIENT; sap++)
536    {
537        if (llcp_cb.client_cb[sap].p_app_cback == NULL)
538        {
539            p_app_cb = &llcp_cb.client_cb[sap];
540            memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
541            reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap;
542            break;
543        }
544    }
545
546    if (reg_sap == LLCP_INVALID_SAP)
547    {
548        LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): out of resource");
549        return LLCP_INVALID_SAP;
550    }
551
552    p_app_cb->p_app_cback    = p_app_cback;
553    p_app_cb->p_service_name = NULL;
554    p_app_cb->link_type      = link_type;
555
556    LLCP_TRACE_DEBUG1 ("LLCP_RegisterClient (): Registered SAP = 0x%02X", reg_sap);
557
558    if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
559    {
560        llcp_cb.num_logical_data_link++;
561        llcp_util_adjust_ll_congestion ();
562    }
563
564    return reg_sap;
565}
566
567/*******************************************************************************
568**
569** Function         LLCP_Deregister
570**
571** Description      Deregister server or client
572**
573**
574** Returns          LLCP_STATUS_SUCCESS if success
575**
576*******************************************************************************/
577tLLCP_STATUS LLCP_Deregister (UINT8 local_sap)
578{
579    UINT8 idx;
580    tLLCP_APP_CB *p_app_cb;
581
582    LLCP_TRACE_API1 ("LLCP_Deregister () SAP:0x%x", local_sap);
583
584    p_app_cb = llcp_util_get_app_cb (local_sap);
585
586    if ((!p_app_cb) || (p_app_cb->p_app_cback == NULL))
587    {
588        LLCP_TRACE_ERROR1 ("LLCP_Deregister (): SAP (0x%x) is not registered", local_sap);
589        return LLCP_STATUS_FAIL;
590    }
591
592    if (p_app_cb->p_service_name)
593        GKI_freebuf (p_app_cb->p_service_name);
594
595    /* update WKS bit map */
596    if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
597    {
598        llcp_cb.lcb.wks &= ~ (1 << local_sap);
599    }
600
601    /* discard any received UI PDU on this SAP */
602    LLCP_FlushLogicalLinkRxData (local_sap);
603    llcp_cb.total_rx_ui_pdu = 0;
604
605    /* deallocate any data link connection on this SAP */
606    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
607    {
608        if (  (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
609            &&(llcp_cb.dlcb[idx].local_sap == local_sap)  )
610        {
611            llcp_util_deallocate_data_link (&llcp_cb.dlcb[idx]);
612        }
613    }
614
615    p_app_cb->p_app_cback = NULL;
616
617    /* discard any pending tx UI PDU from this SAP */
618    while (p_app_cb->ui_xmit_q.p_first)
619    {
620        GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
621        llcp_cb.total_tx_ui_pdu--;
622    }
623
624    if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
625    {
626        llcp_cb.num_logical_data_link--;
627        llcp_util_adjust_ll_congestion ();
628    }
629
630    /* check rx congestion status */
631    llcp_util_check_rx_congested_status ();
632
633    return LLCP_STATUS_SUCCESS;
634}
635
636/*******************************************************************************
637**
638** Function         LLCP_IsLogicalLinkCongested
639**
640** Description      Check if logical link is congested
641**
642**
643** Returns          TRUE if congested
644**
645*******************************************************************************/
646BOOLEAN LLCP_IsLogicalLinkCongested (UINT8 local_sap,
647                                     UINT8 num_pending_ui_pdu,
648                                     UINT8 total_pending_ui_pdu,
649                                     UINT8 total_pending_i_pdu)
650{
651    tLLCP_APP_CB *p_app_cb;
652
653    LLCP_TRACE_API4 ("LLCP_IsLogicalLinkCongested () Local SAP:0x%x, pending = (%d, %d, %d)",
654                     local_sap, num_pending_ui_pdu, total_pending_ui_pdu, total_pending_i_pdu);
655
656    p_app_cb = llcp_util_get_app_cb (local_sap);
657
658    if (  (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
659        ||(p_app_cb == NULL)
660        ||(p_app_cb->p_app_cback == NULL)
661        ||((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
662        ||(p_app_cb->is_ui_tx_congested)  )
663    {
664        return (TRUE);
665    }
666    else if (  (num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
667             ||(total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)
668             ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)  )
669    {
670        /* set flag so LLCP can notify uncongested status later */
671        p_app_cb->is_ui_tx_congested = TRUE;
672
673        return (TRUE);
674    }
675    return (FALSE);
676}
677
678/*******************************************************************************
679**
680** Function         LLCP_SendUI
681**
682** Description      Send connnectionless data to DSAP
683**
684**
685** Returns          LLCP_STATUS_SUCCESS if success
686**                  LLCP_STATUS_CONGESTED if logical link is congested
687**                  LLCP_STATUS_FAIL, otherwise
688**
689*******************************************************************************/
690tLLCP_STATUS LLCP_SendUI (UINT8   ssap,
691                          UINT8   dsap,
692                          BT_HDR *p_buf)
693{
694    tLLCP_STATUS status = LLCP_STATUS_FAIL;
695    tLLCP_APP_CB *p_app_cb;
696
697    LLCP_TRACE_API2 ("LLCP_SendUI () SSAP=0x%x, DSAP=0x%x", ssap, dsap);
698
699    p_app_cb = llcp_util_get_app_cb (ssap);
700
701    if (  (p_app_cb == NULL)
702        ||(p_app_cb->p_app_cback == NULL)  )
703    {
704        LLCP_TRACE_ERROR1 ("LLCP_SendUI (): SSAP (0x%x) is not registered", ssap);
705    }
706    else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
707    {
708        LLCP_TRACE_ERROR1 ("LLCP_SendUI (): Logical link on SSAP (0x%x) is not enabled", ssap);
709    }
710    else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
711    {
712        LLCP_TRACE_ERROR0 ("LLCP_SendUI (): LLCP link is not activated");
713    }
714    else if (  (llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN)
715             ||(llcp_cb.lcb.peer_opt & LLCP_LSC_1)  )
716    {
717        if (p_buf->len <= llcp_cb.lcb.peer_miu)
718        {
719            if (p_buf->offset >= LLCP_MIN_OFFSET)
720            {
721                status = llcp_util_send_ui (ssap, dsap, p_app_cb, p_buf);
722            }
723            else
724            {
725                LLCP_TRACE_ERROR2 ("LLCP_SendUI (): offset (%d) must be %d at least",
726                                    p_buf->offset, LLCP_MIN_OFFSET );
727            }
728        }
729        else
730        {
731            LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Data length shall not be bigger than peer's link MIU");
732        }
733    }
734    else
735    {
736        LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Peer doesn't support connectionless link");
737    }
738
739    if (status == LLCP_STATUS_FAIL)
740    {
741        GKI_freebuf (p_buf);
742    }
743
744    return status;
745}
746
747/*******************************************************************************
748**
749** Function         LLCP_ReadLogicalLinkData
750**
751** Description      Read information of UI PDU for local SAP
752**
753**                  - Remote SAP who sent UI PDU is returned.
754**                  - Information of UI PDU up to max_data_len is copied into p_data.
755**                  - Information of next UI PDU is not concatenated.
756**                  - Recommended max_data_len is link MIU of local device
757**
758** Returns          TRUE if more information of UI PDU or more UI PDU in queue
759**
760*******************************************************************************/
761BOOLEAN LLCP_ReadLogicalLinkData (UINT8  local_sap,
762                                  UINT32 max_data_len,
763                                  UINT8  *p_remote_sap,
764                                  UINT32 *p_data_len,
765                                  UINT8  *p_data)
766{
767    tLLCP_APP_CB *p_app_cb;
768    BT_HDR       *p_buf;
769    UINT8        *p_ui_pdu;
770    UINT16       pdu_hdr, ui_pdu_length;
771
772    LLCP_TRACE_API1 ("LLCP_ReadLogicalLinkData () Local SAP:0x%x", local_sap);
773
774    *p_data_len = 0;
775
776    p_app_cb = llcp_util_get_app_cb (local_sap);
777
778    /* if application is registered */
779    if ((p_app_cb) && (p_app_cb->p_app_cback))
780    {
781        /* if any UI PDU in rx queue */
782        if (p_app_cb->ui_rx_q.p_first)
783        {
784            p_buf    = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
785            p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
786
787            /* get length of UI PDU */
788            BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
789
790            /* get remote SAP from LLCP header */
791            BE_STREAM_TO_UINT16 (pdu_hdr, p_ui_pdu);
792            *p_remote_sap = LLCP_GET_SSAP (pdu_hdr);
793
794            /* layer_specific has the offset to read within UI PDU */
795            p_ui_pdu += p_buf->layer_specific;
796
797            /* copy data up to max_data_len */
798            if (max_data_len >= (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific))
799            {
800                /* copy information without LLCP header */
801                *p_data_len = (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
802
803                /* move to next UI PDU if any */
804                p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next UI PDU */
805                p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
806                p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
807            }
808            else
809            {
810                *p_data_len = max_data_len;
811
812                /* update offset to read from remaining UI PDU next time */
813                p_buf->layer_specific += max_data_len;
814            }
815
816            memcpy (p_data, p_ui_pdu, *p_data_len);
817
818            /* if read all of UI PDU */
819            if (p_buf->len == 0)
820            {
821                GKI_dequeue (&p_app_cb->ui_rx_q);
822                GKI_freebuf (p_buf);
823
824                /* decrease number of received UI PDU in in all of ui_rx_q and check rx congestion status */
825                llcp_cb.total_rx_ui_pdu--;
826                llcp_util_check_rx_congested_status ();
827            }
828        }
829
830        /* if there is more UI PDU in rx queue */
831        if (p_app_cb->ui_rx_q.p_first)
832        {
833            return (TRUE);
834        }
835        else
836        {
837            return (FALSE);
838        }
839    }
840    else
841    {
842        LLCP_TRACE_ERROR1 ("LLCP_ReadLogicalLinkData (): Unregistered SAP:0x%x", local_sap);
843
844        return (FALSE);
845    }
846}
847
848/*******************************************************************************
849**
850** Function         LLCP_FlushLogicalLinkRxData
851**
852** Description      Discard received data in logical data link of local SAP
853**
854**
855** Returns          length of data flushed
856**
857*******************************************************************************/
858UINT32 LLCP_FlushLogicalLinkRxData (UINT8 local_sap)
859{
860    BT_HDR       *p_buf;
861    UINT32       flushed_length = 0;
862    tLLCP_APP_CB *p_app_cb;
863    UINT8        *p_ui_pdu;
864    UINT16       ui_pdu_length;
865
866    LLCP_TRACE_API1 ("LLCP_FlushLogicalLinkRxData () Local SAP:0x%x", local_sap);
867
868    p_app_cb = llcp_util_get_app_cb (local_sap);
869
870    /* if application is registered */
871    if ((p_app_cb) && (p_app_cb->p_app_cback))
872    {
873        /* if any UI PDU in rx queue */
874        while (p_app_cb->ui_rx_q.p_first)
875        {
876            p_buf    = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
877            p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
878
879            /* get length of UI PDU */
880            BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
881
882            flushed_length += (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
883
884            /* move to next UI PDU if any */
885            p_buf->layer_specific = 0;  /* offset */
886            p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
887            p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
888
889            /* if read all of UI PDU */
890            if (p_buf->len == 0)
891            {
892                GKI_dequeue (&p_app_cb->ui_rx_q);
893                GKI_freebuf (p_buf);
894                llcp_cb.total_rx_ui_pdu--;
895            }
896        }
897
898        /* number of received UI PDU is decreased so check rx congestion status */
899        llcp_util_check_rx_congested_status ();
900    }
901    else
902    {
903        LLCP_TRACE_ERROR1 ("LLCP_FlushLogicalLinkRxData (): Unregistered SAP:0x%x", local_sap);
904    }
905
906    return (flushed_length);
907}
908
909/*******************************************************************************
910**
911** Function         LLCP_ConnectReq
912**
913** Description      Create data link connection between registered SAP and DSAP
914**                  in peer LLCP,
915**
916**
917** Returns          LLCP_STATUS_SUCCESS if success
918**                  LLCP_STATUS_FAIL, otherwise
919**
920*******************************************************************************/
921tLLCP_STATUS LLCP_ConnectReq (UINT8                    reg_sap,
922                              UINT8                    dsap,
923                              tLLCP_CONNECTION_PARAMS *p_params)
924{
925    tLLCP_DLCB   *p_dlcb;
926    tLLCP_STATUS status;
927    tLLCP_APP_CB *p_app_cb;
928
929    LLCP_TRACE_API2 ("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
930
931    if (  (llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN)
932        &&((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)  )
933    {
934        LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
935        return LLCP_STATUS_FAIL;
936    }
937
938    p_app_cb = llcp_util_get_app_cb (reg_sap);
939
940    /* if application is registered */
941    if (  (p_app_cb == NULL)
942        ||(p_app_cb->p_app_cback == NULL)  )
943    {
944        LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
945        return LLCP_STATUS_FAIL;
946    }
947
948    if (dsap == LLCP_SAP_LM)
949    {
950        LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
951        return LLCP_STATUS_FAIL;
952    }
953
954    if (dsap == LLCP_SAP_SDP)
955    {
956        if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
957        {
958            LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
959                               strlen (p_params->sn));
960            return LLCP_STATUS_FAIL;
961        }
962    }
963
964    if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
965    {
966        LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
967        return LLCP_STATUS_FAIL;
968    }
969
970    /* check if any pending connection request on this reg_sap */
971    p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
972    if (p_dlcb)
973    {
974        /*
975        ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
976        ** if there is multiple pending connection request on the same local SAP.
977        */
978        LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
979        return LLCP_STATUS_FAIL;
980    }
981
982    p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
983
984    if (p_dlcb)
985    {
986        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
987        if (status != LLCP_STATUS_SUCCESS)
988        {
989            LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
990            llcp_util_deallocate_data_link (p_dlcb);
991            return LLCP_STATUS_FAIL;
992        }
993    }
994    else
995    {
996        return LLCP_STATUS_FAIL;
997    }
998
999    return LLCP_STATUS_SUCCESS;
1000}
1001
1002/*******************************************************************************
1003**
1004** Function         LLCP_ConnectCfm
1005**
1006** Description      Accept connection request from peer LLCP
1007**
1008**
1009** Returns          LLCP_STATUS_SUCCESS if success
1010**                  LLCP_STATUS_FAIL, otherwise
1011**
1012*******************************************************************************/
1013tLLCP_STATUS LLCP_ConnectCfm (UINT8                    local_sap,
1014                              UINT8                    remote_sap,
1015                              tLLCP_CONNECTION_PARAMS *p_params)
1016{
1017    tLLCP_STATUS  status;
1018    tLLCP_DLCB   *p_dlcb;
1019
1020    LLCP_TRACE_API2 ("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
1021                     local_sap, remote_sap);
1022
1023    if (!p_params)
1024    {
1025        LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): tLLCP_CONNECTION_PARAMS must be provided");
1026        return LLCP_STATUS_FAIL;
1027    }
1028    else if (p_params->miu > llcp_cb.lcb.local_link_miu)
1029    {
1030        LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link MIU");
1031        return LLCP_STATUS_FAIL;
1032    }
1033
1034    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1035
1036    if (p_dlcb)
1037    {
1038        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
1039    }
1040    else
1041    {
1042        LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): No data link");
1043        status = LLCP_STATUS_FAIL;
1044    }
1045
1046    return status;
1047}
1048
1049/*******************************************************************************
1050**
1051** Function         LLCP_ConnectReject
1052**
1053** Description      Reject connection request from peer LLCP
1054**
1055**                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
1056**                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
1057**                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
1058**                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
1059**                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
1060**
1061** Returns          LLCP_STATUS_SUCCESS if success
1062**                  LLCP_STATUS_FAIL, otherwise
1063**
1064*******************************************************************************/
1065tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
1066                                 UINT8 remote_sap,
1067                                 UINT8 reason)
1068{
1069    tLLCP_STATUS  status;
1070    tLLCP_DLCB   *p_dlcb;
1071
1072    LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
1073                     local_sap, remote_sap, reason);
1074
1075    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1076
1077    if (p_dlcb)
1078    {
1079        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
1080        llcp_util_deallocate_data_link (p_dlcb);
1081    }
1082    else
1083    {
1084        LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
1085        status = LLCP_STATUS_FAIL;
1086    }
1087
1088    return status;
1089}
1090
1091/*******************************************************************************
1092**
1093** Function         LLCP_IsDataLinkCongested
1094**
1095** Description      Check if data link connection is congested
1096**
1097**
1098** Returns          TRUE if congested
1099**
1100*******************************************************************************/
1101BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
1102                                  UINT8 remote_sap,
1103                                  UINT8 num_pending_i_pdu,
1104                                  UINT8 total_pending_ui_pdu,
1105                                  UINT8 total_pending_i_pdu)
1106{
1107    tLLCP_DLCB   *p_dlcb;
1108
1109    LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
1110                     local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
1111
1112    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1113
1114    if (p_dlcb)
1115    {
1116        if (  (p_dlcb->is_tx_congested)
1117            ||(p_dlcb->remote_busy)  )
1118        {
1119            return (TRUE);
1120        }
1121        else if (  (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
1122                 ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)  )
1123        {
1124            /* set flag so LLCP can notify uncongested status later */
1125            p_dlcb->is_tx_congested = TRUE;
1126            return (TRUE);
1127        }
1128        return (FALSE);
1129    }
1130    return (TRUE);
1131}
1132
1133/*******************************************************************************
1134**
1135** Function         LLCP_SendData
1136**
1137** Description      Send connection-oriented data
1138**
1139**
1140** Returns          LLCP_STATUS_SUCCESS if success
1141**                  LLCP_STATUS_CONGESTED if data link is congested
1142**
1143*******************************************************************************/
1144tLLCP_STATUS LLCP_SendData (UINT8   local_sap,
1145                            UINT8   remote_sap,
1146                            BT_HDR *p_buf)
1147{
1148    tLLCP_STATUS  status = LLCP_STATUS_FAIL;
1149    tLLCP_DLCB   *p_dlcb;
1150
1151    LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
1152                     local_sap, remote_sap);
1153
1154    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1155
1156    if (p_dlcb)
1157    {
1158        if (p_dlcb->remote_miu >= p_buf->len)
1159        {
1160            if (p_buf->offset >= LLCP_MIN_OFFSET)
1161            {
1162                status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
1163            }
1164            else
1165            {
1166                LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
1167                                    p_buf->offset, LLCP_MIN_OFFSET );
1168            }
1169        }
1170        else
1171        {
1172            LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
1173                                p_buf->len, p_dlcb->remote_miu);
1174        }
1175    }
1176    else
1177    {
1178        LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
1179    }
1180
1181    if (status == LLCP_STATUS_FAIL)
1182    {
1183        GKI_freebuf (p_buf);
1184    }
1185
1186    return status;
1187}
1188
1189/*******************************************************************************
1190**
1191** Function         LLCP_ReadDataLinkData
1192**
1193** Description      Read information of I PDU for data link connection
1194**
1195**                  - Information of I PDU up to max_data_len is copied into p_data.
1196**                  - Information of next I PDU is not concatenated.
1197**                  - Recommended max_data_len is data link connection MIU of local
1198**                    end point
1199**
1200** Returns          TRUE if more data in queue
1201**
1202*******************************************************************************/
1203BOOLEAN LLCP_ReadDataLinkData (UINT8  local_sap,
1204                               UINT8  remote_sap,
1205                               UINT32 max_data_len,
1206                               UINT32 *p_data_len,
1207                               UINT8  *p_data)
1208{
1209    tLLCP_DLCB *p_dlcb;
1210    BT_HDR     *p_buf;
1211    UINT8      *p_i_pdu;
1212    UINT16     i_pdu_length;
1213
1214    LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
1215                      local_sap, remote_sap);
1216
1217    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1218
1219    *p_data_len = 0;
1220    if (p_dlcb)
1221    {
1222        /* if any I PDU in rx queue */
1223        if (p_dlcb->i_rx_q.p_first)
1224        {
1225            p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1226            p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1227
1228            /* get length of I PDU */
1229            BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1230
1231            /* layer_specific has the offset to read within I PDU */
1232            p_i_pdu += p_buf->layer_specific;
1233
1234            /* copy data up to max_data_len */
1235            if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
1236            {
1237                /* copy information */
1238                *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
1239
1240                /* move to next I PDU if any */
1241                p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next I PDU */
1242                p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1243                p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1244            }
1245            else
1246            {
1247                *p_data_len = max_data_len;
1248
1249                /* update offset to read from remaining I PDU next time */
1250                p_buf->layer_specific += max_data_len;
1251            }
1252
1253            memcpy (p_data, p_i_pdu, *p_data_len);
1254
1255            if (p_buf->layer_specific == 0)
1256            {
1257                p_dlcb->num_rx_i_pdu--;
1258            }
1259
1260            /* if read all of I PDU */
1261            if (p_buf->len == 0)
1262            {
1263                GKI_dequeue (&p_dlcb->i_rx_q);
1264                GKI_freebuf (p_buf);
1265
1266                /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
1267                llcp_cb.total_rx_i_pdu--;
1268                llcp_util_check_rx_congested_status ();
1269            }
1270        }
1271
1272        /* if getting out of rx congestion */
1273        if (  (!p_dlcb->local_busy)
1274            &&(p_dlcb->is_rx_congested)
1275            &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)  )
1276        {
1277            /* send RR */
1278            p_dlcb->is_rx_congested = FALSE;
1279            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1280        }
1281
1282        /* if there is more I PDU in rx queue */
1283        if (p_dlcb->i_rx_q.p_first)
1284        {
1285            return (TRUE);
1286        }
1287        else
1288        {
1289            return (FALSE);
1290        }
1291    }
1292    else
1293    {
1294        LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
1295
1296        return (FALSE);
1297    }
1298}
1299
1300/*******************************************************************************
1301**
1302** Function         LLCP_FlushDataLinkRxData
1303**
1304** Description      Discard received data in data link connection
1305**
1306**
1307** Returns          length of rx data flushed
1308**
1309*******************************************************************************/
1310UINT32 LLCP_FlushDataLinkRxData (UINT8  local_sap,
1311                                 UINT8  remote_sap)
1312{
1313    tLLCP_DLCB *p_dlcb;
1314    BT_HDR     *p_buf;
1315    UINT32     flushed_length = 0;
1316    UINT8      *p_i_pdu;
1317    UINT16     i_pdu_length;
1318
1319    LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
1320                      local_sap, remote_sap);
1321
1322    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1323
1324    if (p_dlcb)
1325    {
1326        /* if any I PDU in rx queue */
1327        while (p_dlcb->i_rx_q.p_first)
1328        {
1329            p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1330            p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1331
1332            /* get length of I PDU */
1333            BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1334
1335            flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
1336
1337            /* move to next I PDU if any */
1338            p_buf->layer_specific = 0;  /* offset */
1339            p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1340            p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1341
1342            /* if read all of I PDU */
1343            if (p_buf->len == 0)
1344            {
1345                GKI_dequeue (&p_dlcb->i_rx_q);
1346                GKI_freebuf (p_buf);
1347                llcp_cb.total_rx_i_pdu--;
1348            }
1349        }
1350
1351        p_dlcb->num_rx_i_pdu = 0;
1352
1353        /* if getting out of rx congestion */
1354        if (  (!p_dlcb->local_busy)
1355            &&(p_dlcb->is_rx_congested)  )
1356        {
1357            /* send RR */
1358            p_dlcb->is_rx_congested = FALSE;
1359            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1360        }
1361
1362        /* number of received I PDU is decreased so check rx congestion status */
1363        llcp_util_check_rx_congested_status ();
1364    }
1365    else
1366    {
1367        LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
1368    }
1369
1370    return (flushed_length);
1371}
1372
1373/*******************************************************************************
1374**
1375** Function         LLCP_DisconnectReq
1376**
1377** Description      Disconnect data link
1378**                  discard any pending data if flush is set to TRUE
1379**
1380** Returns          LLCP_STATUS_SUCCESS if success
1381**
1382*******************************************************************************/
1383tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
1384                                 UINT8 remote_sap,
1385                                 BOOLEAN flush)
1386{
1387    tLLCP_STATUS  status;
1388    tLLCP_DLCB   *p_dlcb;
1389
1390    LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
1391                     local_sap, remote_sap, flush);
1392
1393    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1394
1395    if (p_dlcb)
1396    {
1397        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1398    }
1399    else
1400    {
1401        LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
1402        status = LLCP_STATUS_FAIL;
1403    }
1404
1405    return status;
1406}
1407
1408/*******************************************************************************
1409**
1410** Function         LLCP_SetTxCompleteNtf
1411**
1412** Description      This function is called to get LLCP_SERVICE_TX_COMPLETE
1413**                  when Tx queue is empty and all PDU is acked.
1414**                  This is one time event, so upper layer shall call this function
1415**                  again to get next LLCP_SERVICE_TX_COMPLETE.
1416**
1417** Returns          LLCP_STATUS_SUCCESS if success
1418**
1419*******************************************************************************/
1420tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8   local_sap,
1421                                    UINT8   remote_sap)
1422{
1423    tLLCP_STATUS  status;
1424    tLLCP_DLCB   *p_dlcb;
1425
1426    LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
1427                      local_sap, remote_sap);
1428
1429    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1430
1431    if (p_dlcb)
1432    {
1433        /* set flag to notify upper later when tx complete */
1434        p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1435        status = LLCP_STATUS_SUCCESS;
1436    }
1437    else
1438    {
1439        LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
1440        status = LLCP_STATUS_FAIL;
1441    }
1442
1443    return status;
1444}
1445
1446/*******************************************************************************
1447**
1448** Function         LLCP_SetLocalBusyStatus
1449**
1450** Description      Set local busy status
1451**
1452**
1453** Returns          LLCP_STATUS_SUCCESS if success
1454**
1455*******************************************************************************/
1456tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8   local_sap,
1457                                      UINT8   remote_sap,
1458                                      BOOLEAN is_busy)
1459{
1460    tLLCP_STATUS  status;
1461    tLLCP_DLCB   *p_dlcb;
1462
1463    LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
1464                      local_sap, is_busy);
1465
1466    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1467
1468    if (p_dlcb)
1469    {
1470        if (p_dlcb->local_busy != is_busy)
1471        {
1472            p_dlcb->local_busy = is_busy;
1473
1474            /* send RR or RNR with valid sequence */
1475            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1476
1477            if (is_busy == FALSE)
1478            {
1479                if (p_dlcb->i_rx_q.count)
1480                {
1481                    llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1482                }
1483            }
1484        }
1485        status = LLCP_STATUS_SUCCESS;
1486    }
1487    else
1488    {
1489        LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
1490        status = LLCP_STATUS_FAIL;
1491    }
1492
1493    return status;
1494}
1495
1496/*******************************************************************************
1497**
1498** Function         LLCP_GetRemoteWKS
1499**
1500** Description      Return well-known service bitmap of connected device
1501**
1502**
1503** Returns          WKS bitmap if success
1504**
1505*******************************************************************************/
1506UINT16 LLCP_GetRemoteWKS (void)
1507{
1508    LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
1509                     (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
1510
1511    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1512        return (llcp_cb.lcb.peer_wks);
1513    else
1514        return (0);
1515}
1516
1517/*******************************************************************************
1518**
1519** Function         LLCP_GetRemoteLSC
1520**
1521** Description      Return link service class of connected device
1522**
1523**
1524** Returns          link service class
1525**
1526*******************************************************************************/
1527UINT8 LLCP_GetRemoteLSC (void)
1528{
1529    LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
1530                     (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1531                     ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
1532
1533    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1534        return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
1535    else
1536        return (LLCP_LSC_UNKNOWN);
1537}
1538
1539/*******************************************************************************
1540**
1541** Function         LLCP_GetLinkMIU
1542**
1543** Description      Return local and remote link MIU
1544**
1545**
1546** Returns          None
1547**
1548*******************************************************************************/
1549LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
1550                               UINT16 *p_remote_link_miu)
1551{
1552    LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
1553
1554    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1555    {
1556        *p_local_link_miu  = llcp_cb.lcb.local_link_miu;
1557        *p_remote_link_miu = llcp_cb.lcb.effective_miu;
1558    }
1559    else
1560    {
1561        *p_local_link_miu  = 0;
1562        *p_remote_link_miu = 0;
1563    }
1564
1565    LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
1566                       *p_local_link_miu, *p_remote_link_miu);
1567}
1568
1569/*******************************************************************************
1570**
1571** Function         LLCP_DiscoverService
1572**
1573** Description      Return SAP of service name in connected device through callback
1574**
1575**
1576** Returns          LLCP_STATUS_SUCCESS if success
1577**
1578*******************************************************************************/
1579tLLCP_STATUS LLCP_DiscoverService (char            *p_name,
1580                                   tLLCP_SDP_CBACK *p_cback,
1581                                   UINT8           *p_tid)
1582{
1583    tLLCP_STATUS  status;
1584    UINT8         i;
1585
1586    LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
1587                      p_name);
1588
1589    if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
1590    {
1591        LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
1592        return LLCP_STATUS_FAIL;
1593    }
1594
1595    if (!p_cback)
1596    {
1597        LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
1598        return LLCP_STATUS_FAIL;
1599    }
1600
1601    /* if peer version is less than V1.1 then SNL is not supported */
1602    if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
1603    {
1604        LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
1605        return LLCP_STATUS_FAIL;
1606    }
1607
1608    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
1609    {
1610        if (!llcp_cb.sdp_cb.transac[i].p_cback)
1611        {
1612            llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
1613            llcp_cb.sdp_cb.next_tid++;
1614            llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
1615
1616            status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
1617
1618            if (status == LLCP_STATUS_FAIL)
1619            {
1620                llcp_cb.sdp_cb.transac[i].p_cback = NULL;
1621            }
1622
1623            *p_tid = llcp_cb.sdp_cb.transac[i].tid;
1624            return (status);
1625        }
1626    }
1627
1628    LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
1629
1630    return LLCP_STATUS_FAIL;
1631}
1632
1633