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