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 NFCEE - API functions
22 *
23 ******************************************************************************/
24#include "nfa_ee_api.h"
25#include <string.h>
26#include "nfa_dm_int.h"
27#include "nfa_ee_int.h"
28#include "nfa_sys_int.h"
29
30/*****************************************************************************
31**  APIs
32*****************************************************************************/
33/*******************************************************************************
34**
35** Function         NFA_EeDiscover
36**
37** Description      This function retrieves the NFCEE information from NFCC.
38**                  The NFCEE information is reported in NFA_EE_DISCOVER_EVT.
39**
40**                  This function may be called when a system supports removable
41**                  NFCEEs,
42**
43** Returns          NFA_STATUS_OK if information is retrieved successfully
44**                  NFA_STATUS_FAILED If wrong state (retry later)
45**                  NFA_STATUS_INVALID_PARAM If bad parameter
46**
47*******************************************************************************/
48tNFA_STATUS NFA_EeDiscover(tNFA_EE_CBACK* p_cback) {
49  tNFA_EE_API_DISCOVER* p_msg;
50  tNFA_STATUS status = NFA_STATUS_FAILED;
51
52  NFA_TRACE_API0("NFA_EeDiscover()");
53
54  if (nfa_ee_cb.em_state != NFA_EE_EM_STATE_INIT_DONE) {
55    NFA_TRACE_ERROR1("NFA_EeDiscover bad em state: %d", nfa_ee_cb.em_state);
56    status = NFA_STATUS_FAILED;
57  } else if ((nfa_ee_cb.p_ee_disc_cback != NULL) || (p_cback == NULL)) {
58    NFA_TRACE_ERROR0("NFA_EeDiscover() in progress or NULL callback function");
59    status = NFA_STATUS_INVALID_PARAM;
60  } else {
61    p_msg = (tNFA_EE_API_DISCOVER*)GKI_getbuf(sizeof(tNFA_EE_API_DISCOVER));
62    if (p_msg != NULL) {
63      p_msg->hdr.event = NFA_EE_API_DISCOVER_EVT;
64      p_msg->p_cback = p_cback;
65
66      nfa_sys_sendmsg(p_msg);
67
68      status = NFA_STATUS_OK;
69    }
70  }
71
72  return status;
73}
74
75/*******************************************************************************
76**
77** Function         NFA_EeGetInfo
78**
79** Description      This function retrieves the NFCEE information from NFA.
80**                  The actual number of NFCEE is returned in p_num_nfcee
81**                  and NFCEE information is returned in p_info
82**
83** Returns          NFA_STATUS_OK if information is retrieved successfully
84**                  NFA_STATUS_FAILED If wrong state (retry later)
85**                  NFA_STATUS_INVALID_PARAM If bad parameter
86**
87*******************************************************************************/
88tNFA_STATUS NFA_EeGetInfo(uint8_t* p_num_nfcee, tNFA_EE_INFO* p_info) {
89  int xx, ret = nfa_ee_cb.cur_ee;
90  tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
91  uint8_t max_ret;
92  uint8_t num_ret = 0;
93
94  NFA_TRACE_DEBUG2("NFA_EeGetInfo em_state:%d cur_ee:%d", nfa_ee_cb.em_state,
95                   nfa_ee_cb.cur_ee);
96  /* validate parameters */
97  if (p_info == NULL || p_num_nfcee == NULL) {
98    NFA_TRACE_ERROR0("NFA_EeGetInfo bad parameter");
99    return (NFA_STATUS_INVALID_PARAM);
100  }
101  max_ret = *p_num_nfcee;
102  *p_num_nfcee = 0;
103  if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT) {
104    NFA_TRACE_ERROR1("NFA_EeGetInfo bad em state: %d", nfa_ee_cb.em_state);
105    return (NFA_STATUS_FAILED);
106  }
107
108  /* compose output */
109  for (xx = 0; (xx < ret) && (num_ret < max_ret); xx++, p_cb++) {
110    NFA_TRACE_DEBUG4("xx:%d max_ret:%d, num_ret:%d ee_status:0x%x", xx, max_ret,
111                     num_ret, p_cb->ee_status);
112    if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) ||
113        (p_cb->ee_status == NFA_EE_STATUS_REMOVED)) {
114      continue;
115    }
116    p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
117    p_info->ee_status = p_cb->ee_status;
118    p_info->num_interface = p_cb->num_interface;
119    p_info->num_tlvs = p_cb->num_tlvs;
120    memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
121    memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
122    p_info++;
123    num_ret++;
124  }
125  NFA_TRACE_DEBUG1("num_ret:%d", num_ret);
126  *p_num_nfcee = num_ret;
127  return (NFA_STATUS_OK);
128}
129
130/*******************************************************************************
131**
132** Function         NFA_EeRegister
133**
134** Description      This function registers a callback function to receive the
135**                  events from NFA-EE module.
136**
137** Returns          NFA_STATUS_OK if successfully initiated
138**                  NFA_STATUS_FAILED otherwise
139**                  NFA_STATUS_INVALID_PARAM If bad parameter
140**
141*******************************************************************************/
142tNFA_STATUS NFA_EeRegister(tNFA_EE_CBACK* p_cback) {
143  tNFA_EE_API_REGISTER* p_msg;
144  tNFA_STATUS status = NFA_STATUS_FAILED;
145
146  NFA_TRACE_API0("NFA_EeRegister()");
147
148  if (p_cback == NULL) {
149    NFA_TRACE_ERROR0("NFA_EeRegister(): with NULL callback function");
150    status = NFA_STATUS_INVALID_PARAM;
151  } else {
152    p_msg = (tNFA_EE_API_REGISTER*)GKI_getbuf(sizeof(tNFA_EE_API_REGISTER));
153    if (p_msg != NULL) {
154      p_msg->hdr.event = NFA_EE_API_REGISTER_EVT;
155      p_msg->p_cback = p_cback;
156
157      nfa_sys_sendmsg(p_msg);
158
159      status = NFA_STATUS_OK;
160    }
161  }
162
163  return status;
164}
165
166/*******************************************************************************
167**
168** Function         NFA_EeDeregister
169**
170** Description      This function de-registers the callback function
171**
172** Returns          NFA_STATUS_OK if successfully initiated
173**                  NFA_STATUS_FAILED otherwise
174**                  NFA_STATUS_INVALID_PARAM If bad parameter
175**
176*******************************************************************************/
177tNFA_STATUS NFA_EeDeregister(tNFA_EE_CBACK* p_cback) {
178  tNFA_EE_API_DEREGISTER* p_msg;
179  tNFA_STATUS status = NFA_STATUS_INVALID_PARAM;
180  int index = NFA_EE_MAX_CBACKS;
181  int xx;
182
183  for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
184    if (nfa_ee_cb.p_ee_cback[xx] == p_cback) {
185      index = xx;
186      status = NFA_STATUS_FAILED;
187      break;
188    }
189  }
190
191  NFA_TRACE_API2("NFA_EeDeregister() %d, status:%d", index, status);
192  if ((status != NFA_STATUS_INVALID_PARAM) &&
193      (p_msg = (tNFA_EE_API_DEREGISTER*)GKI_getbuf(
194           sizeof(tNFA_EE_API_DEREGISTER))) != NULL) {
195    p_msg->hdr.event = NFA_EE_API_DEREGISTER_EVT;
196    p_msg->index = index;
197
198    nfa_sys_sendmsg(p_msg);
199
200    status = NFA_STATUS_OK;
201  }
202
203  return status;
204}
205
206/*******************************************************************************
207**
208** Function         NFA_EeModeSet
209**
210** Description      This function is called to activate
211**                  (mode = NFA_EE_MD_ACTIVATE) or deactivate
212**                  (mode = NFA_EE_MD_DEACTIVATE) the NFCEE identified by the
213**                  given ee_handle. The result of this operation is reported
214**                  with the NFA_EE_MODE_SET_EVT.
215**
216** Returns          NFA_STATUS_OK if successfully initiated
217**                  NFA_STATUS_FAILED otherwise
218**                  NFA_STATUS_INVALID_PARAM If bad parameter
219**
220*******************************************************************************/
221tNFA_STATUS NFA_EeModeSet(tNFA_HANDLE ee_handle, tNFA_EE_MD mode) {
222  tNFA_EE_API_MODE_SET* p_msg;
223  tNFA_STATUS status = NFA_STATUS_FAILED;
224  tNFA_EE_ECB *p_cb, *p_found = NULL;
225  uint32_t xx;
226  uint8_t nfcee_id = (ee_handle & 0xFF);
227
228  p_cb = nfa_ee_cb.ecb;
229  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
230    if (nfcee_id == p_cb->nfcee_id) {
231      p_found = p_cb;
232      break;
233    }
234  }
235  NFA_TRACE_API2("NFA_EeModeSet(): handle:<0x%x>, mode:0x%02X", ee_handle,
236                 mode);
237
238  if (p_found == NULL) {
239    NFA_TRACE_ERROR1("NFA_EeModeSet() invalid NFCEE:0x%04x", ee_handle);
240    status = NFA_STATUS_INVALID_PARAM;
241  } else {
242    p_msg = (tNFA_EE_API_MODE_SET*)GKI_getbuf(sizeof(tNFA_EE_API_MODE_SET));
243    if (p_msg != NULL) {
244      p_msg->hdr.event = NFA_EE_API_MODE_SET_EVT;
245      p_msg->nfcee_id = nfcee_id;
246      p_msg->mode = mode;
247      p_msg->p_cb = p_found;
248
249      nfa_sys_sendmsg(p_msg);
250
251      status = NFA_STATUS_OK;
252    }
253  }
254
255  return status;
256}
257
258/*******************************************************************************
259**
260** Function         NFA_EeSetDefaultTechRouting
261**
262** Description      This function is called to add, change or remove the
263**                  default routing based on RF technology in the listen mode
264**                  routing table for the given ee_handle. The status of this
265**                  operation is reported as the NFA_EE_SET_TECH_CFG_EVT.
266**
267** Note:            If RF discovery is started,
268**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
269**                  happen before calling this function
270**
271** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
272**                  function to change the listen mode routing is called.
273**
274** Returns          NFA_STATUS_OK if successfully initiated
275**                  NFA_STATUS_FAILED otherwise
276**                  NFA_STATUS_INVALID_PARAM If bad parameter
277**
278*******************************************************************************/
279tNFA_STATUS NFA_EeSetDefaultTechRouting(
280    tNFA_HANDLE ee_handle, tNFA_TECHNOLOGY_MASK technologies_switch_on,
281    tNFA_TECHNOLOGY_MASK technologies_switch_off,
282    tNFA_TECHNOLOGY_MASK technologies_battery_off) {
283  tNFA_EE_API_SET_TECH_CFG* p_msg;
284  tNFA_STATUS status = NFA_STATUS_FAILED;
285  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
286  tNFA_EE_ECB* p_cb;
287
288  NFA_TRACE_API4(
289      "NFA_EeSetDefaultTechRouting(): "
290      "handle:<0x%x>technology_mask:<0x%x>/<0x%x>/<0x%x>",
291      ee_handle, technologies_switch_on, technologies_switch_off,
292      technologies_battery_off);
293  p_cb = nfa_ee_find_ecb(nfcee_id);
294
295  if (p_cb == NULL) {
296    NFA_TRACE_ERROR0("Bad ee_handle");
297    status = NFA_STATUS_INVALID_PARAM;
298  } else {
299    p_msg =
300        (tNFA_EE_API_SET_TECH_CFG*)GKI_getbuf(sizeof(tNFA_EE_API_SET_TECH_CFG));
301    if (p_msg != NULL) {
302      p_msg->hdr.event = NFA_EE_API_SET_TECH_CFG_EVT;
303      p_msg->nfcee_id = nfcee_id;
304      p_msg->p_cb = p_cb;
305      p_msg->technologies_switch_on = technologies_switch_on;
306      p_msg->technologies_switch_off = technologies_switch_off;
307      p_msg->technologies_battery_off = technologies_battery_off;
308
309      nfa_sys_sendmsg(p_msg);
310
311      status = NFA_STATUS_OK;
312    }
313  }
314
315  return status;
316}
317
318/*******************************************************************************
319**
320** Function         NFA_EeSetDefaultProtoRouting
321**
322** Description      This function is called to add, change or remove the
323**                  default routing based on Protocol in the listen mode routing
324**                  table for the given ee_handle. The status of this
325**                  operation is reported as the NFA_EE_SET_PROTO_CFG_EVT.
326**
327** Note:            If RF discovery is started,
328**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
329**                  happen before calling this function
330**
331** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
332**                  function to change the listen mode routing is called.
333**
334** Returns          NFA_STATUS_OK if successfully initiated
335**                  NFA_STATUS_FAILED otherwise
336**                  NFA_STATUS_INVALID_PARAM If bad parameter
337**
338*******************************************************************************/
339tNFA_STATUS NFA_EeSetDefaultProtoRouting(
340    tNFA_HANDLE ee_handle, tNFA_PROTOCOL_MASK protocols_switch_on,
341    tNFA_PROTOCOL_MASK protocols_switch_off,
342    tNFA_PROTOCOL_MASK protocols_battery_off) {
343  tNFA_EE_API_SET_PROTO_CFG* p_msg;
344  tNFA_STATUS status = NFA_STATUS_FAILED;
345  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
346  tNFA_EE_ECB* p_cb;
347
348  NFA_TRACE_API4(
349      "NFA_EeSetDefaultProtoRouting(): "
350      "handle:<0x%x>protocol_mask:<0x%x>/<0x%x>/<0x%x>",
351      ee_handle, protocols_switch_on, protocols_switch_off,
352      protocols_battery_off);
353  p_cb = nfa_ee_find_ecb(nfcee_id);
354
355  if (p_cb == NULL) {
356    NFA_TRACE_ERROR0("Bad ee_handle");
357    status = NFA_STATUS_INVALID_PARAM;
358  } else {
359    p_msg = (tNFA_EE_API_SET_PROTO_CFG*)GKI_getbuf(
360        sizeof(tNFA_EE_API_SET_PROTO_CFG));
361    if (p_msg != NULL) {
362      p_msg->hdr.event = NFA_EE_API_SET_PROTO_CFG_EVT;
363      p_msg->nfcee_id = nfcee_id;
364      p_msg->p_cb = p_cb;
365      p_msg->protocols_switch_on = protocols_switch_on;
366      p_msg->protocols_switch_off = protocols_switch_off;
367      p_msg->protocols_battery_off = protocols_battery_off;
368
369      nfa_sys_sendmsg(p_msg);
370
371      status = NFA_STATUS_OK;
372    }
373  }
374
375  return status;
376}
377
378/*******************************************************************************
379**
380** Function         NFA_EeAddAidRouting
381**
382** Description      This function is called to add an AID entry in the
383**                  listen mode routing table in NFCC. The status of this
384**                  operation is reported as the NFA_EE_ADD_AID_EVT.
385**
386** Note:            If RF discovery is started,
387**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
388**                  happen before calling this function
389**
390** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
391**                  function to change the listen mode routing is called.
392**
393** Returns          NFA_STATUS_OK if successfully initiated
394**                  NFA_STATUS_FAILED otherwise
395**                  NFA_STATUS_INVALID_PARAM If bad parameter
396**
397*******************************************************************************/
398tNFA_STATUS NFA_EeAddAidRouting(tNFA_HANDLE ee_handle, uint8_t aid_len,
399                                uint8_t* p_aid, tNFA_EE_PWR_STATE power_state,
400                                uint8_t aidInfo) {
401  tNFA_EE_API_ADD_AID* p_msg;
402  tNFA_STATUS status = NFA_STATUS_FAILED;
403  uint16_t size = sizeof(tNFA_EE_API_ADD_AID) + aid_len;
404  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
405  tNFA_EE_ECB* p_cb;
406
407  NFA_TRACE_API1("NFA_EeAddAidRouting(): handle:<0x%x>", ee_handle);
408  p_cb = nfa_ee_find_ecb(nfcee_id);
409
410  /* validate parameters - make sure the AID is in valid length range */
411  if ((p_cb == NULL) || (aid_len == 0) || (p_aid == NULL) ||
412      (aid_len < NFA_MIN_AID_LEN) || (aid_len > NFA_MAX_AID_LEN)) {
413    NFA_TRACE_ERROR1("Bad ee_handle or AID (len=%d)", aid_len);
414    status = NFA_STATUS_INVALID_PARAM;
415  } else {
416    p_msg = (tNFA_EE_API_ADD_AID*)GKI_getbuf(size);
417    if (p_msg != NULL) {
418      NFA_TRACE_DEBUG2("aid:<%02x%02x>", p_aid[0], p_aid[1]);
419      p_msg->hdr.event = NFA_EE_API_ADD_AID_EVT;
420      p_msg->nfcee_id = nfcee_id;
421      p_msg->p_cb = p_cb;
422      p_msg->aid_len = aid_len;
423      p_msg->power_state = power_state;
424      p_msg->p_aid = (uint8_t*)(p_msg + 1);
425      p_msg->aidInfo = aidInfo;
426      memcpy(p_msg->p_aid, p_aid, aid_len);
427
428      nfa_sys_sendmsg(p_msg);
429
430      status = NFA_STATUS_OK;
431    }
432  }
433
434  return status;
435}
436
437/*******************************************************************************
438**
439** Function         NFA_EeRemoveAidRouting
440**
441** Description      This function is called to remove the given AID entry from
442**                  the listen mode routing table. If the entry configures VS,
443**                  it is also removed. The status of this operation is reported
444**                  as the NFA_EE_REMOVE_AID_EVT.
445**
446** Note:            If RF discovery is started,
447**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
448**                  happen before calling this function
449**
450** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
451**                  function to change the listen mode routing is called.
452**
453** Returns          NFA_STATUS_OK if successfully initiated
454**                  NFA_STATUS_FAILED otherwise
455**                  NFA_STATUS_INVALID_PARAM If bad parameter
456**
457*******************************************************************************/
458tNFA_STATUS NFA_EeRemoveAidRouting(uint8_t aid_len, uint8_t* p_aid) {
459  tNFA_EE_API_REMOVE_AID* p_msg;
460  tNFA_STATUS status = NFA_STATUS_FAILED;
461  uint16_t size = sizeof(tNFA_EE_API_REMOVE_AID) + aid_len;
462
463  NFA_TRACE_API0("NFA_EeRemoveAidRouting()");
464  if ((aid_len == 0) || (p_aid == NULL) || (aid_len > NFA_MAX_AID_LEN)) {
465    NFA_TRACE_ERROR0("Bad AID");
466    status = NFA_STATUS_INVALID_PARAM;
467  } else {
468    p_msg = (tNFA_EE_API_REMOVE_AID*)GKI_getbuf(size);
469    if (p_msg != NULL) {
470      p_msg->hdr.event = NFA_EE_API_REMOVE_AID_EVT;
471      p_msg->aid_len = aid_len;
472      p_msg->p_aid = (uint8_t*)(p_msg + 1);
473      memcpy(p_msg->p_aid, p_aid, aid_len);
474
475      nfa_sys_sendmsg(p_msg);
476
477      status = NFA_STATUS_OK;
478    }
479  }
480
481  return status;
482}
483
484/*******************************************************************************
485**
486** Function         NFA_EeGetLmrtRemainingSize
487**
488** Description      This function is called to get remaining size of the
489**                  Listen Mode Routing Table.
490**                  The remaining size is reported in NFA_EE_REMAINING_SIZE_EVT
491**
492** Returns          NFA_STATUS_OK if successfully initiated
493**                  NFA_STATUS_FAILED otherwise
494**
495*******************************************************************************/
496tNFA_STATUS NFA_EeGetLmrtRemainingSize(void) {
497  tNFA_EE_API_LMRT_SIZE* p_msg;
498  tNFA_STATUS status = NFA_STATUS_FAILED;
499
500  NFA_TRACE_API0("NFA_EeGetLmrtRemainingSize()");
501  p_msg = (tNFA_EE_API_LMRT_SIZE*)GKI_getbuf(sizeof(tNFA_EE_API_LMRT_SIZE));
502  if (p_msg != NULL) {
503    p_msg->event = NFA_EE_API_LMRT_SIZE_EVT;
504    nfa_sys_sendmsg(p_msg);
505    status = NFA_STATUS_OK;
506  }
507
508  return status;
509}
510
511/******************************************************************************
512**
513** Function         NFA_EeUpdateNow
514**
515** Description      This function is called to send the current listen mode
516**                  routing table and VS configuration to the NFCC (without
517**                  waiting for NFA_EE_ROUT_TIMEOUT_VAL).
518**
519**                  The status of this operation is
520**                  reported with the NFA_EE_UPDATED_EVT.
521**
522** Returns          NFA_STATUS_OK if successfully initiated
523**                  NFA_STATUS_SEMANTIC_ERROR is update is currently in progress
524**                  NFA_STATUS_FAILED otherwise
525**
526*******************************************************************************/
527tNFA_STATUS NFA_EeUpdateNow(void) {
528  NFC_HDR* p_msg;
529  tNFA_STATUS status = NFA_STATUS_FAILED;
530
531  NFA_TRACE_API0("NFA_EeUpdateNow()");
532  if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) {
533    NFA_TRACE_ERROR0("update in progress");
534    status = NFA_STATUS_SEMANTIC_ERROR;
535  } else {
536    p_msg = (NFC_HDR*)GKI_getbuf(NFC_HDR_SIZE);
537    if (p_msg != NULL) {
538      p_msg->event = NFA_EE_API_UPDATE_NOW_EVT;
539
540      nfa_sys_sendmsg(p_msg);
541
542      status = NFA_STATUS_OK;
543    }
544  }
545
546  return status;
547}
548
549/*******************************************************************************
550**
551** Function         NFA_EeConnect
552**
553** Description      Open connection to an NFCEE attached to the NFCC
554**
555**                  The status of this operation is
556**                  reported with the NFA_EE_CONNECT_EVT.
557**
558** Returns          NFA_STATUS_OK if successfully initiated
559**                  NFA_STATUS_FAILED otherwise
560**                  NFA_STATUS_INVALID_PARAM If bad parameter
561**
562*******************************************************************************/
563tNFA_STATUS NFA_EeConnect(tNFA_HANDLE ee_handle, uint8_t ee_interface,
564                          tNFA_EE_CBACK* p_cback) {
565  tNFA_EE_API_CONNECT* p_msg;
566  tNFA_STATUS status = NFA_STATUS_FAILED;
567  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
568  tNFA_EE_ECB* p_cb;
569
570  NFA_TRACE_API2("NFA_EeConnect(): handle:<0x%x> ee_interface:0x%x", ee_handle,
571                 ee_interface);
572  p_cb = nfa_ee_find_ecb(nfcee_id);
573
574  if ((p_cb == NULL) || (p_cback == NULL)) {
575    NFA_TRACE_ERROR0("Bad ee_handle or NULL callback function");
576    status = NFA_STATUS_INVALID_PARAM;
577  } else {
578    p_msg = (tNFA_EE_API_CONNECT*)GKI_getbuf(sizeof(tNFA_EE_API_CONNECT));
579    if (p_msg != NULL) {
580      p_msg->hdr.event = NFA_EE_API_CONNECT_EVT;
581      p_msg->nfcee_id = nfcee_id;
582      p_msg->p_cb = p_cb;
583      p_msg->ee_interface = ee_interface;
584      p_msg->p_cback = p_cback;
585
586      nfa_sys_sendmsg(p_msg);
587
588      status = NFA_STATUS_OK;
589    }
590  }
591
592  return status;
593}
594
595/*******************************************************************************
596**
597** Function         NFA_EeSendData
598**
599** Description      Send data to the given NFCEE.
600**                  This function shall be called after NFA_EE_CONNECT_EVT is
601**                  reported and before NFA_EeDisconnect is called on the given
602**                  ee_handle.
603**
604** Returns          NFA_STATUS_OK if successfully initiated
605**                  NFA_STATUS_FAILED otherwise
606**                  NFA_STATUS_INVALID_PARAM If bad parameter
607**
608*******************************************************************************/
609tNFA_STATUS NFA_EeSendData(tNFA_HANDLE ee_handle, uint16_t data_len,
610                           uint8_t* p_data) {
611  tNFA_EE_API_SEND_DATA* p_msg;
612  tNFA_STATUS status = NFA_STATUS_FAILED;
613  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
614  tNFA_EE_ECB* p_cb;
615
616  NFA_TRACE_API1("NFA_EeSendData(): handle:<0x%x>", ee_handle);
617
618  p_cb = nfa_ee_find_ecb(nfcee_id);
619
620  if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN) ||
621      (p_data == NULL)) {
622    NFA_TRACE_ERROR0("Bad ee_handle or NULL data");
623    status = NFA_STATUS_INVALID_PARAM;
624  } else {
625    p_msg = (tNFA_EE_API_SEND_DATA*)GKI_getbuf(
626        (uint16_t)(sizeof(tNFA_EE_API_SEND_DATA) + data_len));
627    if (p_msg != NULL) {
628      p_msg->hdr.event = NFA_EE_API_SEND_DATA_EVT;
629      p_msg->nfcee_id = nfcee_id;
630      p_msg->p_cb = p_cb;
631      p_msg->data_len = data_len;
632      p_msg->p_data = (uint8_t*)(p_msg + 1);
633      memcpy(p_msg->p_data, p_data, data_len);
634
635      nfa_sys_sendmsg(p_msg);
636
637      status = NFA_STATUS_OK;
638    }
639  }
640
641  return status;
642}
643
644/*******************************************************************************
645**
646** Function         NFA_EeDisconnect
647**
648** Description      Disconnect (if a connection is currently open) from an
649**                  NFCEE interface. The result of this operation is reported
650**                  with the NFA_EE_DISCONNECT_EVT.
651**
652** Returns          NFA_STATUS_OK if successfully initiated
653**                  NFA_STATUS_FAILED otherwise
654**                  NFA_STATUS_INVALID_PARAM If bad parameter
655**
656*******************************************************************************/
657tNFA_STATUS NFA_EeDisconnect(tNFA_HANDLE ee_handle) {
658  tNFA_EE_API_DISCONNECT* p_msg;
659  tNFA_STATUS status = NFA_STATUS_FAILED;
660  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
661  tNFA_EE_ECB* p_cb;
662
663  NFA_TRACE_API1("NFA_EeDisconnect(): handle:<0x%x>", ee_handle);
664  p_cb = nfa_ee_find_ecb(nfcee_id);
665
666  if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN)) {
667    NFA_TRACE_ERROR0("NFA_EeDisconnect() Bad ee_handle");
668    status = NFA_STATUS_INVALID_PARAM;
669  } else {
670    p_msg = (tNFA_EE_API_DISCONNECT*)GKI_getbuf(sizeof(tNFA_EE_API_DISCONNECT));
671    if (p_msg != NULL) {
672      p_msg->hdr.event = NFA_EE_API_DISCONNECT_EVT;
673      p_msg->nfcee_id = nfcee_id;
674      p_msg->p_cb = p_cb;
675
676      nfa_sys_sendmsg(p_msg);
677
678      status = NFA_STATUS_OK;
679    }
680  }
681
682  return status;
683}
684