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