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