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