• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 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     tLLCP_CONNECTION_PARAMS params;
912 
913     LLCP_TRACE_API2 ("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
914 
915     if (  (llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN)
916         &&((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)  )
917     {
918         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
919         return LLCP_STATUS_FAIL;
920     }
921 
922     if (!p_params)
923     {
924         params.miu   = LLCP_DEFAULT_MIU;
925         params.rw    = LLCP_DEFAULT_RW;
926         params.sn[0] = 0;
927         p_params     = &params;
928     }
929 
930     p_app_cb = llcp_util_get_app_cb (reg_sap);
931 
932     /* if application is registered */
933     if (  (p_app_cb == NULL)
934         ||(p_app_cb->p_app_cback == NULL)  )
935     {
936         LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
937         return LLCP_STATUS_FAIL;
938     }
939 
940     if (dsap == LLCP_SAP_LM)
941     {
942         LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
943         return LLCP_STATUS_FAIL;
944     }
945 
946     if (dsap == LLCP_SAP_SDP)
947     {
948         if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
949         {
950             LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
951                                strlen (p_params->sn));
952             return LLCP_STATUS_FAIL;
953         }
954     }
955 
956     if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
957     {
958         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
959         return LLCP_STATUS_FAIL;
960     }
961 
962     /* check if any pending connection request on this reg_sap */
963     p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
964     if (p_dlcb)
965     {
966         /*
967         ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
968         ** if there is multiple pending connection request on the same local SAP.
969         */
970         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
971         return LLCP_STATUS_FAIL;
972     }
973 
974     p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
975 
976     if (p_dlcb)
977     {
978         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
979         if (status != LLCP_STATUS_SUCCESS)
980         {
981             LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
982             llcp_util_deallocate_data_link (p_dlcb);
983             return LLCP_STATUS_FAIL;
984         }
985     }
986     else
987     {
988         return LLCP_STATUS_FAIL;
989     }
990 
991     return LLCP_STATUS_SUCCESS;
992 }
993 
994 /*******************************************************************************
995 **
996 ** Function         LLCP_ConnectCfm
997 **
998 ** Description      Accept connection request from peer LLCP
999 **
1000 **
1001 ** Returns          LLCP_STATUS_SUCCESS if success
1002 **                  LLCP_STATUS_FAIL, otherwise
1003 **
1004 *******************************************************************************/
LLCP_ConnectCfm(UINT8 local_sap,UINT8 remote_sap,tLLCP_CONNECTION_PARAMS * p_params)1005 tLLCP_STATUS LLCP_ConnectCfm (UINT8                    local_sap,
1006                               UINT8                    remote_sap,
1007                               tLLCP_CONNECTION_PARAMS *p_params)
1008 {
1009     tLLCP_STATUS  status;
1010     tLLCP_DLCB   *p_dlcb;
1011     tLLCP_CONNECTION_PARAMS params;
1012 
1013     LLCP_TRACE_API2 ("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
1014                      local_sap, remote_sap);
1015 
1016     if (!p_params)
1017     {
1018         params.miu   = LLCP_DEFAULT_MIU;
1019         params.rw    = LLCP_DEFAULT_RW;
1020         params.sn[0] = 0;
1021         p_params     = &params;
1022     }
1023     if (p_params->miu > llcp_cb.lcb.local_link_miu)
1024     {
1025         LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link MIU");
1026         return LLCP_STATUS_FAIL;
1027     }
1028 
1029     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1030 
1031     if (p_dlcb)
1032     {
1033         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
1034     }
1035     else
1036     {
1037         LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): No data link");
1038         status = LLCP_STATUS_FAIL;
1039     }
1040 
1041     return status;
1042 }
1043 
1044 /*******************************************************************************
1045 **
1046 ** Function         LLCP_ConnectReject
1047 **
1048 ** Description      Reject connection request from peer LLCP
1049 **
1050 **                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
1051 **                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
1052 **                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
1053 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
1054 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
1055 **
1056 ** Returns          LLCP_STATUS_SUCCESS if success
1057 **                  LLCP_STATUS_FAIL, otherwise
1058 **
1059 *******************************************************************************/
LLCP_ConnectReject(UINT8 local_sap,UINT8 remote_sap,UINT8 reason)1060 tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
1061                                  UINT8 remote_sap,
1062                                  UINT8 reason)
1063 {
1064     tLLCP_STATUS  status;
1065     tLLCP_DLCB   *p_dlcb;
1066 
1067     LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
1068                      local_sap, remote_sap, reason);
1069 
1070     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1071 
1072     if (p_dlcb)
1073     {
1074         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
1075         llcp_util_deallocate_data_link (p_dlcb);
1076     }
1077     else
1078     {
1079         LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
1080         status = LLCP_STATUS_FAIL;
1081     }
1082 
1083     return status;
1084 }
1085 
1086 /*******************************************************************************
1087 **
1088 ** Function         LLCP_IsDataLinkCongested
1089 **
1090 ** Description      Check if data link connection is congested
1091 **
1092 **
1093 ** Returns          TRUE if congested
1094 **
1095 *******************************************************************************/
LLCP_IsDataLinkCongested(UINT8 local_sap,UINT8 remote_sap,UINT8 num_pending_i_pdu,UINT8 total_pending_ui_pdu,UINT8 total_pending_i_pdu)1096 BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
1097                                   UINT8 remote_sap,
1098                                   UINT8 num_pending_i_pdu,
1099                                   UINT8 total_pending_ui_pdu,
1100                                   UINT8 total_pending_i_pdu)
1101 {
1102     tLLCP_DLCB   *p_dlcb;
1103 
1104     LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
1105                      local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
1106 
1107     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1108 
1109     if (p_dlcb)
1110     {
1111         if (  (p_dlcb->is_tx_congested)
1112             ||(p_dlcb->remote_busy)  )
1113         {
1114             return (TRUE);
1115         }
1116         else if (  (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
1117                  ||(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)  )
1118         {
1119             /* set flag so LLCP can notify uncongested status later */
1120             p_dlcb->is_tx_congested = TRUE;
1121             return (TRUE);
1122         }
1123         return (FALSE);
1124     }
1125     return (TRUE);
1126 }
1127 
1128 /*******************************************************************************
1129 **
1130 ** Function         LLCP_SendData
1131 **
1132 ** Description      Send connection-oriented data
1133 **
1134 **
1135 ** Returns          LLCP_STATUS_SUCCESS if success
1136 **                  LLCP_STATUS_CONGESTED if data link is congested
1137 **
1138 *******************************************************************************/
LLCP_SendData(UINT8 local_sap,UINT8 remote_sap,BT_HDR * p_buf)1139 tLLCP_STATUS LLCP_SendData (UINT8   local_sap,
1140                             UINT8   remote_sap,
1141                             BT_HDR *p_buf)
1142 {
1143     tLLCP_STATUS  status = LLCP_STATUS_FAIL;
1144     tLLCP_DLCB   *p_dlcb;
1145 
1146     LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
1147                      local_sap, remote_sap);
1148 
1149     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1150 
1151     if (p_dlcb)
1152     {
1153         if (p_dlcb->remote_miu >= p_buf->len)
1154         {
1155             if (p_buf->offset >= LLCP_MIN_OFFSET)
1156             {
1157                 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
1158             }
1159             else
1160             {
1161                 LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
1162                                     p_buf->offset, LLCP_MIN_OFFSET );
1163             }
1164         }
1165         else
1166         {
1167             LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
1168                                 p_buf->len, p_dlcb->remote_miu);
1169         }
1170     }
1171     else
1172     {
1173         LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
1174     }
1175 
1176     if (status == LLCP_STATUS_FAIL)
1177     {
1178         GKI_freebuf (p_buf);
1179     }
1180 
1181     return status;
1182 }
1183 
1184 /*******************************************************************************
1185 **
1186 ** Function         LLCP_ReadDataLinkData
1187 **
1188 ** Description      Read information of I PDU for data link connection
1189 **
1190 **                  - Information of I PDU up to max_data_len is copied into p_data.
1191 **                  - Information of next I PDU is not concatenated.
1192 **                  - Recommended max_data_len is data link connection MIU of local
1193 **                    end point
1194 **
1195 ** Returns          TRUE if more data in queue
1196 **
1197 *******************************************************************************/
LLCP_ReadDataLinkData(UINT8 local_sap,UINT8 remote_sap,UINT32 max_data_len,UINT32 * p_data_len,UINT8 * p_data)1198 BOOLEAN LLCP_ReadDataLinkData (UINT8  local_sap,
1199                                UINT8  remote_sap,
1200                                UINT32 max_data_len,
1201                                UINT32 *p_data_len,
1202                                UINT8  *p_data)
1203 {
1204     tLLCP_DLCB *p_dlcb;
1205     BT_HDR     *p_buf;
1206     UINT8      *p_i_pdu;
1207     UINT16     i_pdu_length;
1208 
1209     LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
1210                       local_sap, remote_sap);
1211 
1212     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1213 
1214     *p_data_len = 0;
1215     if (p_dlcb)
1216     {
1217         /* if any I PDU in rx queue */
1218         if (p_dlcb->i_rx_q.p_first)
1219         {
1220             p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1221             p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1222 
1223             /* get length of I PDU */
1224             BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1225 
1226             /* layer_specific has the offset to read within I PDU */
1227             p_i_pdu += p_buf->layer_specific;
1228 
1229             /* copy data up to max_data_len */
1230             if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
1231             {
1232                 /* copy information */
1233                 *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
1234 
1235                 /* move to next I PDU if any */
1236                 p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next I PDU */
1237                 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1238                 p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1239             }
1240             else
1241             {
1242                 *p_data_len = max_data_len;
1243 
1244                 /* update offset to read from remaining I PDU next time */
1245                 p_buf->layer_specific += max_data_len;
1246             }
1247 
1248             memcpy (p_data, p_i_pdu, *p_data_len);
1249 
1250             if (p_buf->layer_specific == 0)
1251             {
1252                 p_dlcb->num_rx_i_pdu--;
1253             }
1254 
1255             /* if read all of I PDU */
1256             if (p_buf->len == 0)
1257             {
1258                 GKI_dequeue (&p_dlcb->i_rx_q);
1259                 GKI_freebuf (p_buf);
1260 
1261                 /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
1262                 llcp_cb.total_rx_i_pdu--;
1263                 llcp_util_check_rx_congested_status ();
1264             }
1265         }
1266 
1267         /* if getting out of rx congestion */
1268         if (  (!p_dlcb->local_busy)
1269             &&(p_dlcb->is_rx_congested)
1270             &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)  )
1271         {
1272             /* send RR */
1273             p_dlcb->is_rx_congested = FALSE;
1274             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1275         }
1276 
1277         /* if there is more I PDU in rx queue */
1278         if (p_dlcb->i_rx_q.p_first)
1279         {
1280             return (TRUE);
1281         }
1282         else
1283         {
1284             return (FALSE);
1285         }
1286     }
1287     else
1288     {
1289         LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
1290 
1291         return (FALSE);
1292     }
1293 }
1294 
1295 /*******************************************************************************
1296 **
1297 ** Function         LLCP_FlushDataLinkRxData
1298 **
1299 ** Description      Discard received data in data link connection
1300 **
1301 **
1302 ** Returns          length of rx data flushed
1303 **
1304 *******************************************************************************/
LLCP_FlushDataLinkRxData(UINT8 local_sap,UINT8 remote_sap)1305 UINT32 LLCP_FlushDataLinkRxData (UINT8  local_sap,
1306                                  UINT8  remote_sap)
1307 {
1308     tLLCP_DLCB *p_dlcb;
1309     BT_HDR     *p_buf;
1310     UINT32     flushed_length = 0;
1311     UINT8      *p_i_pdu;
1312     UINT16     i_pdu_length;
1313 
1314     LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
1315                       local_sap, remote_sap);
1316 
1317     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1318 
1319     if (p_dlcb)
1320     {
1321         /* if any I PDU in rx queue */
1322         while (p_dlcb->i_rx_q.p_first)
1323         {
1324             p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
1325             p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
1326 
1327             /* get length of I PDU */
1328             BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
1329 
1330             flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
1331 
1332             /* move to next I PDU if any */
1333             p_buf->layer_specific = 0;  /* offset */
1334             p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1335             p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1336 
1337             /* if read all of I PDU */
1338             if (p_buf->len == 0)
1339             {
1340                 GKI_dequeue (&p_dlcb->i_rx_q);
1341                 GKI_freebuf (p_buf);
1342                 llcp_cb.total_rx_i_pdu--;
1343             }
1344         }
1345 
1346         p_dlcb->num_rx_i_pdu = 0;
1347 
1348         /* if getting out of rx congestion */
1349         if (  (!p_dlcb->local_busy)
1350             &&(p_dlcb->is_rx_congested)  )
1351         {
1352             /* send RR */
1353             p_dlcb->is_rx_congested = FALSE;
1354             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1355         }
1356 
1357         /* number of received I PDU is decreased so check rx congestion status */
1358         llcp_util_check_rx_congested_status ();
1359     }
1360     else
1361     {
1362         LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
1363     }
1364 
1365     return (flushed_length);
1366 }
1367 
1368 /*******************************************************************************
1369 **
1370 ** Function         LLCP_DisconnectReq
1371 **
1372 ** Description      Disconnect data link
1373 **                  discard any pending data if flush is set to TRUE
1374 **
1375 ** Returns          LLCP_STATUS_SUCCESS if success
1376 **
1377 *******************************************************************************/
LLCP_DisconnectReq(UINT8 local_sap,UINT8 remote_sap,BOOLEAN flush)1378 tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
1379                                  UINT8 remote_sap,
1380                                  BOOLEAN flush)
1381 {
1382     tLLCP_STATUS  status;
1383     tLLCP_DLCB   *p_dlcb;
1384 
1385     LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
1386                      local_sap, remote_sap, flush);
1387 
1388     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1389 
1390     if (p_dlcb)
1391     {
1392         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1393     }
1394     else
1395     {
1396         LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
1397         status = LLCP_STATUS_FAIL;
1398     }
1399 
1400     return status;
1401 }
1402 
1403 /*******************************************************************************
1404 **
1405 ** Function         LLCP_SetTxCompleteNtf
1406 **
1407 ** Description      This function is called to get LLCP_SERVICE_TX_COMPLETE
1408 **                  when Tx queue is empty and all PDU is acked.
1409 **                  This is one time event, so upper layer shall call this function
1410 **                  again to get next LLCP_SERVICE_TX_COMPLETE.
1411 **
1412 ** Returns          LLCP_STATUS_SUCCESS if success
1413 **
1414 *******************************************************************************/
LLCP_SetTxCompleteNtf(UINT8 local_sap,UINT8 remote_sap)1415 tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8   local_sap,
1416                                     UINT8   remote_sap)
1417 {
1418     tLLCP_STATUS  status;
1419     tLLCP_DLCB   *p_dlcb;
1420 
1421     LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
1422                       local_sap, remote_sap);
1423 
1424     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1425 
1426     if (p_dlcb)
1427     {
1428         /* set flag to notify upper later when tx complete */
1429         p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1430         status = LLCP_STATUS_SUCCESS;
1431     }
1432     else
1433     {
1434         LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
1435         status = LLCP_STATUS_FAIL;
1436     }
1437 
1438     return status;
1439 }
1440 
1441 /*******************************************************************************
1442 **
1443 ** Function         LLCP_SetLocalBusyStatus
1444 **
1445 ** Description      Set local busy status
1446 **
1447 **
1448 ** Returns          LLCP_STATUS_SUCCESS if success
1449 **
1450 *******************************************************************************/
LLCP_SetLocalBusyStatus(UINT8 local_sap,UINT8 remote_sap,BOOLEAN is_busy)1451 tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8   local_sap,
1452                                       UINT8   remote_sap,
1453                                       BOOLEAN is_busy)
1454 {
1455     tLLCP_STATUS  status;
1456     tLLCP_DLCB   *p_dlcb;
1457 
1458     LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
1459                       local_sap, is_busy);
1460 
1461     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
1462 
1463     if (p_dlcb)
1464     {
1465         if (p_dlcb->local_busy != is_busy)
1466         {
1467             p_dlcb->local_busy = is_busy;
1468 
1469             /* send RR or RNR with valid sequence */
1470             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1471 
1472             if (is_busy == FALSE)
1473             {
1474                 if (p_dlcb->i_rx_q.count)
1475                 {
1476                     llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1477                 }
1478             }
1479         }
1480         status = LLCP_STATUS_SUCCESS;
1481     }
1482     else
1483     {
1484         LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
1485         status = LLCP_STATUS_FAIL;
1486     }
1487 
1488     return status;
1489 }
1490 
1491 /*******************************************************************************
1492 **
1493 ** Function         LLCP_GetRemoteWKS
1494 **
1495 ** Description      Return well-known service bitmap of connected device
1496 **
1497 **
1498 ** Returns          WKS bitmap if success
1499 **
1500 *******************************************************************************/
LLCP_GetRemoteWKS(void)1501 UINT16 LLCP_GetRemoteWKS (void)
1502 {
1503     LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
1504                      (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
1505 
1506     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1507         return (llcp_cb.lcb.peer_wks);
1508     else
1509         return (0);
1510 }
1511 
1512 /*******************************************************************************
1513 **
1514 ** Function         LLCP_GetRemoteLSC
1515 **
1516 ** Description      Return link service class of connected device
1517 **
1518 **
1519 ** Returns          link service class
1520 **
1521 *******************************************************************************/
LLCP_GetRemoteLSC(void)1522 UINT8 LLCP_GetRemoteLSC (void)
1523 {
1524     LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
1525                      (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1526                      ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
1527 
1528     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1529         return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
1530     else
1531         return (LLCP_LSC_UNKNOWN);
1532 }
1533 
1534 /*******************************************************************************
1535 **
1536 ** Function         LLCP_GetLinkMIU
1537 **
1538 ** Description      Return local and remote link MIU
1539 **
1540 **
1541 ** Returns          None
1542 **
1543 *******************************************************************************/
LLCP_GetLinkMIU(UINT16 * p_local_link_miu,UINT16 * p_remote_link_miu)1544 LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
1545                                UINT16 *p_remote_link_miu)
1546 {
1547     LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
1548 
1549     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1550     {
1551         *p_local_link_miu  = llcp_cb.lcb.local_link_miu;
1552         *p_remote_link_miu = llcp_cb.lcb.effective_miu;
1553     }
1554     else
1555     {
1556         *p_local_link_miu  = 0;
1557         *p_remote_link_miu = 0;
1558     }
1559 
1560     LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
1561                        *p_local_link_miu, *p_remote_link_miu);
1562 }
1563 
1564 /*******************************************************************************
1565 **
1566 ** Function         LLCP_DiscoverService
1567 **
1568 ** Description      Return SAP of service name in connected device through callback
1569 **
1570 **
1571 ** Returns          LLCP_STATUS_SUCCESS if success
1572 **
1573 *******************************************************************************/
LLCP_DiscoverService(char * p_name,tLLCP_SDP_CBACK * p_cback,UINT8 * p_tid)1574 tLLCP_STATUS LLCP_DiscoverService (char            *p_name,
1575                                    tLLCP_SDP_CBACK *p_cback,
1576                                    UINT8           *p_tid)
1577 {
1578     tLLCP_STATUS  status;
1579     UINT8         i;
1580 
1581     LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
1582                       p_name);
1583 
1584     if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
1585     {
1586         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
1587         return LLCP_STATUS_FAIL;
1588     }
1589 
1590     if (!p_cback)
1591     {
1592         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
1593         return LLCP_STATUS_FAIL;
1594     }
1595 
1596     /* if peer version is less than V1.1 then SNL is not supported */
1597     if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
1598     {
1599         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
1600         return LLCP_STATUS_FAIL;
1601     }
1602 
1603     for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
1604     {
1605         if (!llcp_cb.sdp_cb.transac[i].p_cback)
1606         {
1607             llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
1608             llcp_cb.sdp_cb.next_tid++;
1609             llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
1610 
1611             status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
1612 
1613             if (status == LLCP_STATUS_FAIL)
1614             {
1615                 llcp_cb.sdp_cb.transac[i].p_cback = NULL;
1616             }
1617 
1618             *p_tid = llcp_cb.sdp_cb.transac[i].tid;
1619             return (status);
1620         }
1621     }
1622 
1623     LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
1624 
1625     return LLCP_STATUS_FAIL;
1626 }
1627 
1628