1/******************************************************************************
2 *
3 *  Copyright (C) 2010-2014 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  NFA interface to LLCP
22 *
23 ******************************************************************************/
24#include "nfa_p2p_api.h"
25#include <string.h>
26#include "llcp_api.h"
27#include "llcp_defs.h"
28#include "nfa_p2p_int.h"
29#include "nfa_sys.h"
30#include "nfa_sys_int.h"
31#include "nfc_api.h"
32
33/*****************************************************************************
34**  Constants
35*****************************************************************************/
36
37/*******************************************************************************
38**
39** Function         NFA_P2pRegisterServer
40**
41** Description      This function is called to listen to a SAP as server on
42**                  LLCP.
43**
44**                  NFA_P2P_REG_SERVER_EVT will be returned with status and
45**                  handle.
46**
47**                  If server_sap is set to NFA_P2P_ANY_SAP, then NFA will
48**                  allocate a SAP between LLCP_LOWER_BOUND_SDP_SAP and
49**                  LLCP_UPPER_BOUND_SDP_SAP Otherwise, server_sap must be
50**                  between (LLCP_SDP_SAP + 1) and LLCP_UPPER_BOUND_SDP_SAP
51**
52**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
53**
54** Note:            If RF discovery is started,
55**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
56**                  happen before calling this function
57**
58** Returns          NFA_STATUS_OK if successfully initiated
59**                  NFA_STATUS_FAILED otherwise
60**
61*******************************************************************************/
62tNFA_STATUS NFA_P2pRegisterServer(uint8_t server_sap,
63                                  tNFA_P2P_LINK_TYPE link_type,
64                                  char* p_service_name,
65                                  tNFA_P2P_CBACK* p_cback) {
66  tNFA_P2P_API_REG_SERVER* p_msg;
67
68  P2P_TRACE_API3(
69      "NFA_P2pRegisterServer (): server_sap:0x%02x, link_type:0x%x, SN:<%s>",
70      server_sap, link_type, p_service_name);
71
72  if ((server_sap != NFA_P2P_ANY_SAP) &&
73      ((server_sap <= LLCP_SAP_SDP) ||
74       (server_sap > LLCP_UPPER_BOUND_SDP_SAP))) {
75    P2P_TRACE_ERROR2(
76        "NFA_P2pRegisterServer (): server_sap must be between %d and %d",
77        LLCP_SAP_SDP + 1, LLCP_UPPER_BOUND_SDP_SAP);
78    return (NFA_STATUS_FAILED);
79  } else if (((link_type & NFA_P2P_LLINK_TYPE) == 0x00) &&
80             ((link_type & NFA_P2P_DLINK_TYPE) == 0x00)) {
81    P2P_TRACE_ERROR1(
82        "NFA_P2pRegisterServer(): link type (0x%x) must be specified",
83        link_type);
84    return (NFA_STATUS_FAILED);
85  }
86
87  if ((p_msg = (tNFA_P2P_API_REG_SERVER*)GKI_getbuf(
88           sizeof(tNFA_P2P_API_REG_SERVER))) != NULL) {
89    p_msg->hdr.event = NFA_P2P_API_REG_SERVER_EVT;
90
91    p_msg->server_sap = server_sap;
92    p_msg->link_type = link_type;
93
94    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
95    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
96
97    p_msg->p_cback = p_cback;
98
99    nfa_sys_sendmsg(p_msg);
100
101    return (NFA_STATUS_OK);
102  }
103
104  return (NFA_STATUS_FAILED);
105}
106
107/*******************************************************************************
108**
109** Function         NFA_P2pRegisterClient
110**
111** Description      This function is called to register a client service on
112**                  LLCP.
113**
114**                  NFA_P2P_REG_CLIENT_EVT will be returned with status and
115**                  handle.
116**
117**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
118**
119** Returns          NFA_STATUS_OK if successfully initiated
120**                  NFA_STATUS_FAILED otherwise
121**
122*******************************************************************************/
123tNFA_STATUS NFA_P2pRegisterClient(tNFA_P2P_LINK_TYPE link_type,
124                                  tNFA_P2P_CBACK* p_cback) {
125  tNFA_P2P_API_REG_CLIENT* p_msg;
126
127  P2P_TRACE_API1("NFA_P2pRegisterClient (): link_type:0x%x", link_type);
128
129  if (((link_type & NFA_P2P_LLINK_TYPE) == 0x00) &&
130      ((link_type & NFA_P2P_DLINK_TYPE) == 0x00)) {
131    P2P_TRACE_ERROR1(
132        "NFA_P2pRegisterClient (): link type (0x%x) must be specified",
133        link_type);
134    return (NFA_STATUS_FAILED);
135  }
136
137  if ((p_msg = (tNFA_P2P_API_REG_CLIENT*)GKI_getbuf(
138           sizeof(tNFA_P2P_API_REG_CLIENT))) != NULL) {
139    p_msg->hdr.event = NFA_P2P_API_REG_CLIENT_EVT;
140
141    p_msg->p_cback = p_cback;
142    p_msg->link_type = link_type;
143
144    nfa_sys_sendmsg(p_msg);
145
146    return (NFA_STATUS_OK);
147  }
148
149  return (NFA_STATUS_FAILED);
150}
151
152/*******************************************************************************
153**
154** Function         NFA_P2pDeregister
155**
156** Description      This function is called to stop listening to a SAP as server
157**                  or stop client service on LLCP.
158**
159** Note:            If this function is called to de-register a server and RF
160**                  discovery is started,
161**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
162**                  happen before calling this function
163**
164** Returns          NFA_STATUS_OK if successfully initiated
165**                  NFA_STATUS_BAD_HANDLE if handle is not valid
166**                  NFA_STATUS_FAILED otherwise
167**
168*******************************************************************************/
169tNFA_STATUS NFA_P2pDeregister(tNFA_HANDLE handle) {
170  tNFA_P2P_API_DEREG* p_msg;
171  tNFA_HANDLE xx;
172
173  P2P_TRACE_API1("NFA_P2pDeregister (): handle:0x%02X", handle);
174
175  xx = handle & NFA_HANDLE_MASK;
176
177  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
178    P2P_TRACE_ERROR0(
179        "NFA_P2pDeregister (): Handle is invalid or not registered");
180    return (NFA_STATUS_BAD_HANDLE);
181  }
182
183  if ((p_msg = (tNFA_P2P_API_DEREG*)GKI_getbuf(sizeof(tNFA_P2P_API_DEREG))) !=
184      NULL) {
185    p_msg->hdr.event = NFA_P2P_API_DEREG_EVT;
186
187    p_msg->handle = handle;
188
189    nfa_sys_sendmsg(p_msg);
190
191    return (NFA_STATUS_OK);
192  }
193
194  return (NFA_STATUS_FAILED);
195}
196
197/*******************************************************************************
198**
199** Function         NFA_P2pAcceptConn
200**
201** Description      This function is called to accept a request of data link
202**                  connection to a listening SAP on LLCP after receiving
203**                  NFA_P2P_CONN_REQ_EVT.
204**
205** Returns          NFA_STATUS_OK if successfully initiated
206**                  NFA_STATUS_BAD_HANDLE if handle is not valid
207**                  NFA_STATUS_FAILED otherwise
208**
209*******************************************************************************/
210tNFA_STATUS NFA_P2pAcceptConn(tNFA_HANDLE handle, uint16_t miu, uint8_t rw) {
211  tNFA_P2P_API_ACCEPT_CONN* p_msg;
212  tNFA_HANDLE xx;
213
214  P2P_TRACE_API3("NFA_P2pAcceptConn (): handle:0x%02X, MIU:%d, RW:%d", handle,
215                 miu, rw);
216
217  xx = handle & NFA_HANDLE_MASK;
218
219  if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) {
220    P2P_TRACE_ERROR0("NFA_P2pAcceptConn (): Connection Handle is not valid");
221    return (NFA_STATUS_BAD_HANDLE);
222  } else {
223    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
224  }
225
226  if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
227    P2P_TRACE_ERROR0("NFA_P2pAcceptConn (): Connection Handle is not valid");
228    return (NFA_STATUS_BAD_HANDLE);
229  }
230
231  if ((miu < LLCP_DEFAULT_MIU) || (nfa_p2p_cb.local_link_miu < miu)) {
232    P2P_TRACE_ERROR3("NFA_P2pAcceptConn (): MIU(%d) must be between %d and %d",
233                     miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
234  } else if ((p_msg = (tNFA_P2P_API_ACCEPT_CONN*)GKI_getbuf(
235                  sizeof(tNFA_P2P_API_ACCEPT_CONN))) != NULL) {
236    p_msg->hdr.event = NFA_P2P_API_ACCEPT_CONN_EVT;
237
238    p_msg->conn_handle = handle;
239    p_msg->miu = miu;
240    p_msg->rw = rw;
241
242    nfa_sys_sendmsg(p_msg);
243
244    return (NFA_STATUS_OK);
245  }
246
247  return (NFA_STATUS_FAILED);
248}
249
250/*******************************************************************************
251**
252** Function         NFA_P2pRejectConn
253**
254** Description      This function is called to reject a request of data link
255**                  connection to a listening SAP on LLCP after receiving
256**                  NFA_P2P_CONN_REQ_EVT.
257**
258** Returns          NFA_STATUS_OK if successfully initiated
259**                  NFA_STATUS_BAD_HANDLE if handle is not valid
260**                  NFA_STATUS_FAILED otherwise
261**
262*******************************************************************************/
263tNFA_STATUS NFA_P2pRejectConn(tNFA_HANDLE handle) {
264  tNFA_P2P_API_REJECT_CONN* p_msg;
265  tNFA_HANDLE xx;
266
267  P2P_TRACE_API1("NFA_P2pRejectConn (): handle:0x%02X", handle);
268
269  xx = handle & NFA_HANDLE_MASK;
270
271  if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) {
272    P2P_TRACE_ERROR0("NFA_P2pRejectConn (): Connection Handle is not valid");
273    return (NFA_STATUS_BAD_HANDLE);
274  } else {
275    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
276  }
277
278  if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
279    P2P_TRACE_ERROR0("NFA_P2pRejectConn (): Connection Handle is not valid");
280    return (NFA_STATUS_BAD_HANDLE);
281  }
282
283  if ((p_msg = (tNFA_P2P_API_REJECT_CONN*)GKI_getbuf(
284           sizeof(tNFA_P2P_API_REJECT_CONN))) != NULL) {
285    p_msg->hdr.event = NFA_P2P_API_REJECT_CONN_EVT;
286
287    p_msg->conn_handle = handle;
288
289    nfa_sys_sendmsg(p_msg);
290
291    return (NFA_STATUS_OK);
292  }
293
294  return (NFA_STATUS_FAILED);
295}
296
297/*******************************************************************************
298**
299** Function         NFA_P2pDisconnect
300**
301** Description      This function is called to disconnect an existing or
302**                  connecting data link connection.
303**
304**                  discard any pending data on data link connection if flush is
305**                  set to TRUE
306**
307**                  NFA_P2P_DISC_EVT will be returned after data link connection
308**                  is disconnected
309**
310** Returns          NFA_STATUS_OK if successfully initiated
311**                  NFA_STATUS_BAD_HANDLE if handle is not valid
312**                  NFA_STATUS_FAILED otherwise
313**
314*******************************************************************************/
315tNFA_STATUS NFA_P2pDisconnect(tNFA_HANDLE handle, bool flush) {
316  tNFA_P2P_API_DISCONNECT* p_msg;
317  tNFA_HANDLE xx;
318
319  P2P_TRACE_API2("NFA_P2pDisconnect (): handle:0x%02X, flush=%d", handle,
320                 flush);
321
322  xx = handle & NFA_HANDLE_MASK;
323
324  if (xx & NFA_P2P_HANDLE_FLAG_CONN) {
325    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
326
327    if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
328      P2P_TRACE_ERROR0("NFA_P2pDisconnect (): Connection Handle is not valid");
329      return (NFA_STATUS_BAD_HANDLE);
330    }
331  } else {
332    P2P_TRACE_ERROR0("NFA_P2pDisconnect (): Handle is not valid");
333    return (NFA_STATUS_BAD_HANDLE);
334  }
335
336  if ((p_msg = (tNFA_P2P_API_DISCONNECT*)GKI_getbuf(
337           sizeof(tNFA_P2P_API_DISCONNECT))) != NULL) {
338    p_msg->hdr.event = NFA_P2P_API_DISCONNECT_EVT;
339
340    p_msg->conn_handle = handle;
341    p_msg->flush = flush;
342
343    nfa_sys_sendmsg(p_msg);
344
345    return (NFA_STATUS_OK);
346  }
347
348  return (NFA_STATUS_FAILED);
349}
350
351/*******************************************************************************
352**
353** Function         NFA_P2pConnectByName
354**
355** Description      This function is called to create a connection-oriented
356**                  transport by a service name.
357**                  NFA_P2P_CONNECTED_EVT if success
358**                  NFA_P2P_DISC_EVT if failed
359**
360** Returns          NFA_STATUS_OK if successfully initiated
361**                  NFA_STATUS_BAD_HANDLE if client is not registered
362**                  NFA_STATUS_FAILED otherwise
363**
364*******************************************************************************/
365tNFA_STATUS NFA_P2pConnectByName(tNFA_HANDLE client_handle,
366                                 char* p_service_name, uint16_t miu,
367                                 uint8_t rw) {
368  tNFA_P2P_API_CONNECT* p_msg;
369  tNFA_HANDLE xx;
370
371  P2P_TRACE_API4(
372      "NFA_P2pConnectByName (): client_handle:0x%x, SN:<%s>, MIU:%d, RW:%d",
373      client_handle, p_service_name, miu, rw);
374
375  xx = client_handle & NFA_HANDLE_MASK;
376
377  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
378    P2P_TRACE_ERROR0("NFA_P2pConnectByName (): Client Handle is not valid");
379    return (NFA_STATUS_BAD_HANDLE);
380  }
381
382  if ((miu < LLCP_DEFAULT_MIU) ||
383      (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) ||
384      (nfa_p2p_cb.local_link_miu < miu)) {
385    P2P_TRACE_ERROR3(
386        "NFA_P2pConnectByName (): MIU(%d) must be between %d and %d or LLCP "
387        "link is not activated",
388        miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
389  } else if ((p_msg = (tNFA_P2P_API_CONNECT*)GKI_getbuf(
390                  sizeof(tNFA_P2P_API_CONNECT))) != NULL) {
391    p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
392
393    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
394    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
395
396    p_msg->dsap = LLCP_INVALID_SAP;
397    p_msg->miu = miu;
398    p_msg->rw = rw;
399    p_msg->client_handle = client_handle;
400
401    nfa_sys_sendmsg(p_msg);
402
403    return (NFA_STATUS_OK);
404  }
405
406  return (NFA_STATUS_FAILED);
407}
408
409/*******************************************************************************
410**
411** Function         NFA_P2pConnectBySap
412**
413** Description      This function is called to create a connection-oriented
414**                  transport by a SAP.
415**                  NFA_P2P_CONNECTED_EVT if success
416**                  NFA_P2P_DISC_EVT if failed
417**
418** Returns          NFA_STATUS_OK if successfully initiated
419**                  NFA_STATUS_BAD_HANDLE if client is not registered
420**                  NFA_STATUS_FAILED otherwise
421**
422*******************************************************************************/
423tNFA_STATUS NFA_P2pConnectBySap(tNFA_HANDLE client_handle, uint8_t dsap,
424                                uint16_t miu, uint8_t rw) {
425  tNFA_P2P_API_CONNECT* p_msg;
426  tNFA_HANDLE xx;
427
428  P2P_TRACE_API4(
429      "NFA_P2pConnectBySap (): client_handle:0x%x, DSAP:0x%02X, MIU:%d, RW:%d",
430      client_handle, dsap, miu, rw);
431
432  xx = client_handle & NFA_HANDLE_MASK;
433
434  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
435    P2P_TRACE_ERROR0("NFA_P2pConnectBySap (): Client Handle is not valid");
436    return (NFA_STATUS_BAD_HANDLE);
437  }
438
439  if ((miu < LLCP_DEFAULT_MIU) ||
440      (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) ||
441      (nfa_p2p_cb.local_link_miu < miu)) {
442    P2P_TRACE_ERROR3(
443        "NFA_P2pConnectBySap (): MIU(%d) must be between %d and %d, or LLCP "
444        "link is not activated",
445        miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
446  } else if ((p_msg = (tNFA_P2P_API_CONNECT*)GKI_getbuf(
447                  sizeof(tNFA_P2P_API_CONNECT))) != NULL) {
448    p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
449
450    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
451
452    p_msg->dsap = dsap;
453    p_msg->miu = miu;
454    p_msg->rw = rw;
455    p_msg->client_handle = client_handle;
456
457    nfa_sys_sendmsg(p_msg);
458
459    return (NFA_STATUS_OK);
460  }
461
462  return (NFA_STATUS_FAILED);
463}
464
465/*******************************************************************************
466**
467** Function         NFA_P2pSendUI
468**
469** Description      This function is called to send data on connectionless
470**                  transport.
471**
472** Returns          NFA_STATUS_OK if successfully initiated
473**                  NFA_STATUS_BAD_HANDLE if handle is not valid
474**                  NFA_STATUS_BAD_LENGTH if data length is more than remote
475**                  link MIU
476**                  NFA_STATUS_CONGESTED  if congested
477**                  NFA_STATUS_FAILED otherwise
478**
479*******************************************************************************/
480tNFA_STATUS NFA_P2pSendUI(tNFA_HANDLE handle, uint8_t dsap, uint16_t length,
481                          uint8_t* p_data) {
482  tNFA_P2P_API_SEND_UI* p_msg;
483  tNFA_STATUS ret_status = NFA_STATUS_FAILED;
484  tNFA_HANDLE xx;
485
486  P2P_TRACE_API3("NFA_P2pSendUI (): handle:0x%X, DSAP:0x%02X, length:%d",
487                 handle, dsap, length);
488
489  GKI_sched_lock();
490
491  xx = handle & NFA_HANDLE_MASK;
492
493  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
494    P2P_TRACE_ERROR1("NFA_P2pSendUI (): Handle (0x%X) is not valid", handle);
495    ret_status = NFA_STATUS_BAD_HANDLE;
496  } else if (length > nfa_p2p_cb.remote_link_miu) {
497    P2P_TRACE_ERROR3(
498        "NFA_P2pSendUI (): handle:0x%X, length(%d) must be less than remote "
499        "link MIU(%d)",
500        handle, length, nfa_p2p_cb.remote_link_miu);
501    ret_status = NFA_STATUS_BAD_LENGTH;
502  } else if (nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED) {
503    P2P_TRACE_WARNING1(
504        "NFA_P2pSendUI (): handle:0x%X, logical data link is already congested",
505        handle);
506    ret_status = NFA_STATUS_CONGESTED;
507  } else if (LLCP_IsLogicalLinkCongested(
508                 (uint8_t)xx, nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu,
509                 nfa_p2p_cb.total_pending_ui_pdu,
510                 nfa_p2p_cb.total_pending_i_pdu)) {
511    nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
512
513    P2P_TRACE_WARNING1(
514        "NFA_P2pSendUI(): handle:0x%X, logical data link is congested", handle);
515    ret_status = NFA_STATUS_CONGESTED;
516  } else if ((p_msg = (tNFA_P2P_API_SEND_UI*)GKI_getbuf(
517                  sizeof(tNFA_P2P_API_SEND_UI))) != NULL) {
518    p_msg->hdr.event = NFA_P2P_API_SEND_UI_EVT;
519
520    p_msg->handle = handle;
521    p_msg->dsap = dsap;
522
523    p_msg->p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
524    if (p_msg->p_msg != NULL) {
525      p_msg->p_msg->len = length;
526      p_msg->p_msg->offset = LLCP_MIN_OFFSET;
527      memcpy(((uint8_t*)(p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data,
528             length);
529
530      /* increase number of tx UI PDU which is not processed by NFA for
531       * congestion control */
532      nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu++;
533      nfa_p2p_cb.total_pending_ui_pdu++;
534      nfa_sys_sendmsg(p_msg);
535
536      ret_status = NFA_STATUS_OK;
537    } else {
538      GKI_freebuf(p_msg);
539
540      nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
541      ret_status = NFA_STATUS_CONGESTED;
542    }
543  }
544
545  GKI_sched_unlock();
546
547  return (ret_status);
548}
549
550/*******************************************************************************
551**
552** Function         NFA_P2pReadUI
553**
554** Description      This function is called to read data on connectionless
555**                  transport when receiving NFA_P2P_DATA_EVT with
556**                  NFA_P2P_LLINK_TYPE.
557**
558**                  - Remote SAP who sent UI PDU is returned.
559**                  - Information of UI PDU up to max_data_len is copied into
560**                    p_data.
561**                  - If more information of UI PDU or more UI PDU in queue then
562**                    more is returned to TRUE.
563**                  - Information of next UI PDU is not concatenated.
564**
565** Returns          NFA_STATUS_OK if successfully initiated
566**                  NFA_STATUS_BAD_HANDLE if handle is not valid
567**
568*******************************************************************************/
569tNFA_STATUS NFA_P2pReadUI(tNFA_HANDLE handle, uint32_t max_data_len,
570                          uint8_t* p_remote_sap, uint32_t* p_data_len,
571                          uint8_t* p_data, bool* p_more) {
572  tNFA_STATUS ret_status;
573  tNFA_HANDLE xx;
574
575  P2P_TRACE_API1("NFA_P2pReadUI (): handle:0x%X", handle);
576
577  GKI_sched_lock();
578
579  xx = handle & NFA_HANDLE_MASK;
580
581  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
582    P2P_TRACE_ERROR1("NFA_P2pReadUI (): Handle (0x%X) is not valid", handle);
583    ret_status = NFA_STATUS_BAD_HANDLE;
584  } else {
585    *p_more = LLCP_ReadLogicalLinkData((uint8_t)xx, max_data_len, p_remote_sap,
586                                       p_data_len, p_data);
587    ret_status = NFA_STATUS_OK;
588  }
589
590  GKI_sched_unlock();
591
592  return (ret_status);
593}
594
595/*******************************************************************************
596**
597** Function         NFA_P2pFlushUI
598**
599** Description      This function is called to flush data on connectionless
600**                  transport.
601**
602** Returns          NFA_STATUS_OK if successfully initiated
603**                  NFA_STATUS_BAD_HANDLE if handle is not valid
604**
605*******************************************************************************/
606tNFA_STATUS NFA_P2pFlushUI(tNFA_HANDLE handle, uint32_t* p_length) {
607  tNFA_STATUS ret_status;
608  tNFA_HANDLE xx;
609
610  P2P_TRACE_API1("NFA_P2pReadUI (): handle:0x%X", handle);
611
612  GKI_sched_lock();
613
614  xx = handle & NFA_HANDLE_MASK;
615
616  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
617    P2P_TRACE_ERROR1("NFA_P2pFlushUI (): Handle (0x%X) is not valid", handle);
618    ret_status = NFA_STATUS_BAD_HANDLE;
619    *p_length = 0;
620  } else {
621    *p_length = LLCP_FlushLogicalLinkRxData((uint8_t)xx);
622    ret_status = NFA_STATUS_OK;
623  }
624
625  GKI_sched_unlock();
626
627  return (ret_status);
628}
629
630/*******************************************************************************
631**
632** Function         NFA_P2pSendData
633**
634** Description      This function is called to send data on connection-oriented
635**                  transport.
636**
637** Returns          NFA_STATUS_OK if successfully initiated
638**                  NFA_STATUS_BAD_HANDLE if handle is not valid
639**                  NFA_STATUS_BAD_LENGTH if data length is more than remote MIU
640**                  NFA_STATUS_CONGESTED  if congested
641**                  NFA_STATUS_FAILED otherwise
642**
643*******************************************************************************/
644tNFA_STATUS NFA_P2pSendData(tNFA_HANDLE handle, uint16_t length,
645                            uint8_t* p_data) {
646  tNFA_P2P_API_SEND_DATA* p_msg;
647  tNFA_STATUS ret_status = NFA_STATUS_FAILED;
648  tNFA_HANDLE xx;
649
650  P2P_TRACE_API2("NFA_P2pSendData (): handle:0x%X, length:%d", handle, length);
651
652  GKI_sched_lock();
653
654  xx = handle & NFA_HANDLE_MASK;
655  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
656
657  if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) ||
658      (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
659    P2P_TRACE_ERROR1("NFA_P2pSendData (): Handle(0x%X) is not valid", handle);
660    ret_status = NFA_STATUS_BAD_HANDLE;
661  } else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO) {
662    P2P_TRACE_ERROR1(
663        "NFA_P2pSendData (): handle:0x%X, Remote set RW to 0 (flow off)",
664        handle);
665    ret_status = NFA_STATUS_FAILED;
666  } else if (nfa_p2p_cb.conn_cb[xx].remote_miu < length) {
667    P2P_TRACE_ERROR2(
668        "NFA_P2pSendData (): handle:0x%X, Data more than remote MIU(%d)",
669        handle, nfa_p2p_cb.conn_cb[xx].remote_miu);
670    ret_status = NFA_STATUS_BAD_LENGTH;
671  } else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED) {
672    P2P_TRACE_WARNING1(
673        "NFA_P2pSendData (): handle:0x%X, data link connection is already "
674        "congested",
675        handle);
676    ret_status = NFA_STATUS_CONGESTED;
677  } else if (LLCP_IsDataLinkCongested(nfa_p2p_cb.conn_cb[xx].local_sap,
678                                      nfa_p2p_cb.conn_cb[xx].remote_sap,
679                                      nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu,
680                                      nfa_p2p_cb.total_pending_ui_pdu,
681                                      nfa_p2p_cb.total_pending_i_pdu)) {
682    nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
683
684    P2P_TRACE_WARNING1(
685        "NFA_P2pSendData (): handle:0x%X, data link connection is congested",
686        handle);
687    ret_status = NFA_STATUS_CONGESTED;
688  } else if ((p_msg = (tNFA_P2P_API_SEND_DATA*)GKI_getbuf(
689                  sizeof(tNFA_P2P_API_SEND_DATA))) != NULL) {
690    p_msg->hdr.event = NFA_P2P_API_SEND_DATA_EVT;
691
692    p_msg->conn_handle = handle;
693
694    p_msg->p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
695    if (p_msg->p_msg != NULL) {
696      p_msg->p_msg->len = length;
697      p_msg->p_msg->offset = LLCP_MIN_OFFSET;
698      memcpy(((uint8_t*)(p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data,
699             length);
700
701      /* increase number of tx I PDU which is not processed by NFA for
702       * congestion control */
703      nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu++;
704      nfa_p2p_cb.total_pending_i_pdu++;
705      nfa_sys_sendmsg(p_msg);
706
707      ret_status = NFA_STATUS_OK;
708    } else {
709      GKI_freebuf(p_msg);
710      nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
711      ret_status = NFA_STATUS_CONGESTED;
712    }
713  }
714
715  GKI_sched_unlock();
716
717  return (ret_status);
718}
719
720/*******************************************************************************
721**
722** Function         NFA_P2pReadData
723**
724** Description      This function is called to read data on connection-oriented
725**                  transport when receiving NFA_P2P_DATA_EVT with
726**                  NFA_P2P_DLINK_TYPE.
727**
728**                  - Information of I PDU is copied into p_data up to
729**                    max_data_len.
730**                  - If more information of I PDU or more I PDU in queue, then
731**                    more is returned to TRUE.
732**                  - Information of next I PDU is not concatenated.
733**
734** Returns          NFA_STATUS_OK if successfully initiated
735**                  NFA_STATUS_BAD_HANDLE if handle is not valid
736**
737*******************************************************************************/
738tNFA_STATUS NFA_P2pReadData(tNFA_HANDLE handle, uint32_t max_data_len,
739                            uint32_t* p_data_len, uint8_t* p_data,
740                            bool* p_more) {
741  tNFA_STATUS ret_status;
742  tNFA_HANDLE xx;
743
744  P2P_TRACE_API1("NFA_P2pReadData (): handle:0x%X", handle);
745
746  GKI_sched_lock();
747
748  xx = handle & NFA_HANDLE_MASK;
749  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
750
751  if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) ||
752      (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
753    P2P_TRACE_ERROR1("NFA_P2pReadData (): Handle(0x%X) is not valid", handle);
754    ret_status = NFA_STATUS_BAD_HANDLE;
755  } else {
756    *p_more = LLCP_ReadDataLinkData(nfa_p2p_cb.conn_cb[xx].local_sap,
757                                    nfa_p2p_cb.conn_cb[xx].remote_sap,
758                                    max_data_len, p_data_len, p_data);
759    ret_status = NFA_STATUS_OK;
760  }
761
762  GKI_sched_unlock();
763
764  return (ret_status);
765}
766
767/*******************************************************************************
768**
769** Function         NFA_P2pFlushData
770**
771** Description      This function is called to flush data on connection-oriented
772**                  transport.
773**
774** Returns          NFA_STATUS_OK if successfully initiated
775**                  NFA_STATUS_BAD_HANDLE if handle is not valid
776**
777*******************************************************************************/
778tNFA_STATUS NFA_P2pFlushData(tNFA_HANDLE handle, uint32_t* p_length) {
779  tNFA_STATUS ret_status;
780  tNFA_HANDLE xx;
781
782  P2P_TRACE_API1("NFA_P2pFlushData (): handle:0x%X", handle);
783
784  GKI_sched_lock();
785
786  xx = handle & NFA_HANDLE_MASK;
787  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
788
789  if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) ||
790      (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
791    P2P_TRACE_ERROR1("NFA_P2pFlushData (): Handle(0x%X) is not valid", handle);
792    ret_status = NFA_STATUS_BAD_HANDLE;
793  } else {
794    *p_length = LLCP_FlushDataLinkRxData(nfa_p2p_cb.conn_cb[xx].local_sap,
795                                         nfa_p2p_cb.conn_cb[xx].remote_sap);
796    ret_status = NFA_STATUS_OK;
797  }
798
799  GKI_sched_unlock();
800
801  return (ret_status);
802}
803
804/*******************************************************************************
805**
806** Function         NFA_P2pSetLocalBusy
807**
808** Description      This function is called to stop or resume incoming data on
809**                  connection-oriented transport.
810**
811** Returns          NFA_STATUS_OK if successfully initiated
812**                  NFA_STATUS_BAD_HANDLE if handle is not valid
813**                  NFA_STATUS_FAILED otherwise
814**
815*******************************************************************************/
816tNFA_STATUS NFA_P2pSetLocalBusy(tNFA_HANDLE conn_handle, bool is_busy) {
817  tNFA_P2P_API_SET_LOCAL_BUSY* p_msg;
818  tNFA_HANDLE xx;
819
820  P2P_TRACE_API2("NFA_P2pSetLocalBusy (): conn_handle:0x%02X, is_busy:%d",
821                 conn_handle, is_busy);
822
823  xx = conn_handle & NFA_HANDLE_MASK;
824
825  if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) {
826    P2P_TRACE_ERROR0("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
827    return (NFA_STATUS_BAD_HANDLE);
828  } else {
829    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
830  }
831
832  if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
833    P2P_TRACE_ERROR0("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
834    return (NFA_STATUS_BAD_HANDLE);
835  }
836
837  if ((p_msg = (tNFA_P2P_API_SET_LOCAL_BUSY*)GKI_getbuf(
838           sizeof(tNFA_P2P_API_SET_LOCAL_BUSY))) != NULL) {
839    p_msg->hdr.event = NFA_P2P_API_SET_LOCAL_BUSY_EVT;
840
841    p_msg->conn_handle = conn_handle;
842    p_msg->is_busy = is_busy;
843
844    nfa_sys_sendmsg(p_msg);
845
846    return (NFA_STATUS_OK);
847  }
848
849  return (NFA_STATUS_FAILED);
850}
851
852/*******************************************************************************
853**
854** Function         NFA_P2pGetLinkInfo
855**
856** Description      This function is called to get local/remote link MIU and
857**                  Well-Known Service list encoded as a 16-bit field of
858**                  connected LLCP. NFA_P2P_LINK_INFO_EVT will be returned.
859**
860** Returns          NFA_STATUS_OK if successfully initiated
861**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
862**                  NFA_STATUS_FAILED otherwise
863**
864*******************************************************************************/
865tNFA_STATUS NFA_P2pGetLinkInfo(tNFA_HANDLE handle) {
866  tNFA_P2P_API_GET_LINK_INFO* p_msg;
867  tNFA_HANDLE xx;
868
869  P2P_TRACE_API1("NFA_P2pGetLinkInfo (): handle:0x%x", handle);
870
871  if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) {
872    P2P_TRACE_ERROR0("NFA_P2pGetLinkInfo (): LLCP link is not activated");
873    return (NFA_STATUS_FAILED);
874  }
875
876  xx = handle & NFA_HANDLE_MASK;
877
878  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
879    P2P_TRACE_ERROR0(
880        "NFA_P2pGetLinkInfo (): Handle is invalid or not registered");
881    return (NFA_STATUS_BAD_HANDLE);
882  }
883
884  if ((p_msg = (tNFA_P2P_API_GET_LINK_INFO*)GKI_getbuf(
885           sizeof(tNFA_P2P_API_GET_LINK_INFO))) != NULL) {
886    p_msg->hdr.event = NFA_P2P_API_GET_LINK_INFO_EVT;
887
888    p_msg->handle = handle;
889
890    nfa_sys_sendmsg(p_msg);
891
892    return (NFA_STATUS_OK);
893  }
894
895  return (NFA_STATUS_FAILED);
896}
897
898/*******************************************************************************
899**
900** Function         NFA_P2pGetRemoteSap
901**
902** Description      This function is called to get SAP associated by service
903**                  name on connected remote LLCP.
904**                  NFA_P2P_SDP_EVT will be returned.
905**
906** Returns          NFA_STATUS_OK if successfully initiated
907**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
908**                  NFA_STATUS_FAILED otherwise
909**
910*******************************************************************************/
911tNFA_STATUS NFA_P2pGetRemoteSap(tNFA_HANDLE handle, char* p_service_name) {
912  tNFA_P2P_API_GET_REMOTE_SAP* p_msg;
913  tNFA_HANDLE xx;
914
915  P2P_TRACE_API2("NFA_P2pGetRemoteSap(): handle:0x%x, SN:<%s>", handle,
916                 p_service_name);
917
918  if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) {
919    P2P_TRACE_ERROR0("NFA_P2pGetRemoteSap(): LLCP link is not activated");
920    return (NFA_STATUS_FAILED);
921  }
922
923  xx = handle & NFA_HANDLE_MASK;
924
925  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
926    P2P_TRACE_ERROR0(
927        "NFA_P2pGetRemoteSap (): Handle is invalid or not registered");
928    return (NFA_STATUS_BAD_HANDLE);
929  }
930
931  if ((p_msg = (tNFA_P2P_API_GET_REMOTE_SAP*)GKI_getbuf(
932           sizeof(tNFA_P2P_API_GET_REMOTE_SAP))) != NULL) {
933    p_msg->hdr.event = NFA_P2P_API_GET_REMOTE_SAP_EVT;
934
935    p_msg->handle = handle;
936
937    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
938    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
939
940    nfa_sys_sendmsg(p_msg);
941
942    return (NFA_STATUS_OK);
943  }
944
945  return (NFA_STATUS_FAILED);
946}
947
948/*******************************************************************************
949**
950** Function         NFA_P2pSetLLCPConfig
951**
952** Description      This function is called to change LLCP config parameters.
953**                  Application must call while LLCP is not activated.
954**
955**                  Parameters descriptions (default value)
956**                  - Local Link MIU (LLCP_MIU)
957**                  - Option parameter (LLCP_OPT_VALUE)
958**                  - Response Waiting Time Index (LLCP_WAITING_TIME)
959**                  - Local Link Timeout (LLCP_LTO_VALUE)
960**                  - Inactivity Timeout as initiator role
961**                    (LLCP_INIT_INACTIVITY_TIMEOUT)
962**                  - Inactivity Timeout as target role
963**                    (LLCP_TARGET_INACTIVITY_TIMEOUT)
964**                  - Delay SYMM response (LLCP_DELAY_RESP_TIME)
965**                  - Data link connection timeout
966**                    (LLCP_DATA_LINK_CONNECTION_TOUT)
967**                  - Delay timeout to send first PDU as initiator
968**                    (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
969**
970** Returns          NFA_STATUS_OK if successfully initiated
971**                  NFA_STATUS_FAILED otherwise
972**
973*******************************************************************************/
974tNFA_STATUS NFA_P2pSetLLCPConfig(uint16_t link_miu, uint8_t opt, uint8_t wt,
975                                 uint16_t link_timeout,
976                                 uint16_t inact_timeout_init,
977                                 uint16_t inact_timeout_target,
978                                 uint16_t symm_delay,
979                                 uint16_t data_link_timeout,
980                                 uint16_t delay_first_pdu_timeout) {
981  tNFA_P2P_API_SET_LLCP_CFG* p_msg;
982
983  P2P_TRACE_API4(
984      "NFA_P2pSetLLCPConfig ():link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
985      link_miu, opt, wt, link_timeout);
986  P2P_TRACE_API4(
987      "                       inact_timeout(init:%d, target:%d), "
988      "symm_delay:%d, data_link_timeout:%d",
989      inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
990  P2P_TRACE_API1("                       delay_first_pdu_timeout:%d",
991                 delay_first_pdu_timeout);
992
993  if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) {
994    P2P_TRACE_ERROR0("NFA_P2pSetLLCPConfig (): LLCP link is activated");
995    return (NFA_STATUS_FAILED);
996  }
997
998  if ((p_msg = (tNFA_P2P_API_SET_LLCP_CFG*)GKI_getbuf(
999           sizeof(tNFA_P2P_API_SET_LLCP_CFG))) != NULL) {
1000    p_msg->hdr.event = NFA_P2P_API_SET_LLCP_CFG_EVT;
1001
1002    p_msg->link_miu = link_miu;
1003    p_msg->opt = opt;
1004    p_msg->wt = wt;
1005    p_msg->link_timeout = link_timeout;
1006    p_msg->inact_timeout_init = inact_timeout_init;
1007    p_msg->inact_timeout_target = inact_timeout_target;
1008    p_msg->symm_delay = symm_delay;
1009    p_msg->data_link_timeout = data_link_timeout;
1010    p_msg->delay_first_pdu_timeout = delay_first_pdu_timeout;
1011
1012    nfa_sys_sendmsg(p_msg);
1013
1014    return (NFA_STATUS_OK);
1015  }
1016
1017  return (NFA_STATUS_FAILED);
1018}
1019
1020/*******************************************************************************
1021**
1022** Function         NFA_P2pGetLLCPConfig
1023**
1024** Description      This function is called to read LLCP config parameters.
1025**
1026**                  Parameters descriptions
1027**                  - Local Link MIU
1028**                  - Option parameter
1029**                  - Response Waiting Time Index
1030**                  - Local Link Timeout
1031**                  - Inactivity Timeout as initiator role
1032**                  - Inactivity Timeout as target role
1033**                  - Delay SYMM response
1034**                  - Data link connection timeout
1035**                  - Delay timeout to send first PDU as initiator
1036**
1037** Returns          None
1038**
1039*******************************************************************************/
1040void NFA_P2pGetLLCPConfig(uint16_t* p_link_miu, uint8_t* p_opt, uint8_t* p_wt,
1041                          uint16_t* p_link_timeout,
1042                          uint16_t* p_inact_timeout_init,
1043                          uint16_t* p_inact_timeout_target,
1044                          uint16_t* p_symm_delay, uint16_t* p_data_link_timeout,
1045                          uint16_t* p_delay_first_pdu_timeout) {
1046  LLCP_GetConfig(p_link_miu, p_opt, p_wt, p_link_timeout, p_inact_timeout_init,
1047                 p_inact_timeout_target, p_symm_delay, p_data_link_timeout,
1048                 p_delay_first_pdu_timeout);
1049
1050  P2P_TRACE_API4(
1051      "NFA_P2pGetLLCPConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
1052      *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
1053  P2P_TRACE_API4(
1054      "                       inact_timeout(init:%d, target:%d), "
1055      "symm_delay:%d, data_link_timeout:%d",
1056      *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay,
1057      *p_data_link_timeout);
1058  P2P_TRACE_API1("                       delay_first_pdu_timeout:%d",
1059                 *p_delay_first_pdu_timeout);
1060}
1061
1062/*******************************************************************************
1063**
1064** Function         NFA_P2pSetTraceLevel
1065**
1066** Description      This function sets the trace level for P2P.  If called with
1067**                  a value of 0xFF, it simply returns the current trace level.
1068**
1069** Returns          The new or current trace level
1070**
1071*******************************************************************************/
1072uint8_t NFA_P2pSetTraceLevel(uint8_t new_level) {
1073  if (new_level != 0xFF) nfa_p2p_cb.trace_level = new_level;
1074
1075  return (nfa_p2p_cb.trace_level);
1076}
1077