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