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 != nullptr) || (p_cback == nullptr)) {
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 != nullptr) {
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 == nullptr || p_num_nfcee == nullptr) {
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 == nullptr) {
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 != nullptr) {
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))) != nullptr) {
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 = nullptr;
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 == nullptr) {
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 != nullptr) {
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 == nullptr) {
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 != nullptr) {
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_EeClearDefaultTechRouting
340 **
341 ** Description      This function is called to remove the default routing based
342 **                  on RF technology in the listen mode routing table for the
343 **                  given ee_handle. The status of this operation is reported
344 **                  as the NFA_EE_CLEAR_TECH_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_EeClearDefaultTechRouting(tNFA_HANDLE ee_handle,tNFA_TECHNOLOGY_MASK clear_technology)358 tNFA_STATUS NFA_EeClearDefaultTechRouting(
359     tNFA_HANDLE ee_handle, tNFA_TECHNOLOGY_MASK clear_technology) {
360   tNFA_EE_API_SET_TECH_CFG* p_msg;
361   tNFA_STATUS status = NFA_STATUS_FAILED;
362   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
363   tNFA_EE_ECB* p_cb;
364 
365   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
366       "handle:<0x%x>clear technology_mask:<0x%x>", ee_handle, clear_technology);
367   if (!clear_technology) {
368     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("nothing to clear");
369     status = NFA_STATUS_OK;
370     return status;
371   }
372 
373   p_cb = nfa_ee_find_ecb(nfcee_id);
374 
375   if (p_cb == nullptr) {
376     LOG(ERROR) << StringPrintf("Bad ee_handle");
377     status = NFA_STATUS_INVALID_PARAM;
378   } else {
379     p_msg = (tNFA_EE_API_CLEAR_TECH_CFG*)GKI_getbuf(
380         sizeof(tNFA_EE_API_CLEAR_TECH_CFG));
381     if (p_msg != nullptr) {
382       p_msg->hdr.event = NFA_EE_API_CLEAR_TECH_CFG_EVT;
383       p_msg->nfcee_id = nfcee_id;
384       p_msg->p_cb = p_cb;
385       p_msg->technologies_switch_on = clear_technology;
386       p_msg->technologies_switch_off = clear_technology;
387       p_msg->technologies_battery_off = clear_technology;
388       p_msg->technologies_screen_lock = clear_technology;
389       p_msg->technologies_screen_off = clear_technology;
390       p_msg->technologies_screen_off_lock = clear_technology;
391 
392       nfa_sys_sendmsg(p_msg);
393 
394       status = NFA_STATUS_OK;
395     }
396   }
397 
398   return status;
399 }
400 
401 /*******************************************************************************
402 **
403 ** Function         NFA_EeSetDefaultProtoRouting
404 **
405 ** Description      This function is called to add, change or remove the
406 **                  default routing based on Protocol in the listen mode routing
407 **                  table for the given ee_handle. The status of this
408 **                  operation is reported as the NFA_EE_SET_PROTO_CFG_EVT.
409 **
410 ** Note:            If RF discovery is started,
411 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
412 **                  happen before calling this function
413 **
414 ** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
415 **                  function to change the listen mode routing is called.
416 **
417 ** Returns          NFA_STATUS_OK if successfully initiated
418 **                  NFA_STATUS_FAILED otherwise
419 **                  NFA_STATUS_INVALID_PARAM If bad parameter
420 **
421 *******************************************************************************/
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)422 tNFA_STATUS NFA_EeSetDefaultProtoRouting(
423     tNFA_HANDLE ee_handle, tNFA_PROTOCOL_MASK protocols_switch_on,
424     tNFA_PROTOCOL_MASK protocols_switch_off,
425     tNFA_PROTOCOL_MASK protocols_battery_off,
426     tNFA_PROTOCOL_MASK protocols_screen_lock,
427     tNFA_PROTOCOL_MASK protocols_screen_off,
428     tNFA_PROTOCOL_MASK protocols_screen_off_lock) {
429   tNFA_EE_API_SET_PROTO_CFG* p_msg;
430   tNFA_STATUS status = NFA_STATUS_FAILED;
431   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
432   tNFA_EE_ECB* p_cb;
433 
434   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
435       "handle:<0x%x>protocol_mask:<0x%x>/<0x%x>/<0x%x><0x%x><0x%x><0x%x>",
436       ee_handle, protocols_switch_on, protocols_switch_off,
437       protocols_battery_off, protocols_screen_lock, protocols_screen_off,
438       protocols_screen_off_lock);
439   p_cb = nfa_ee_find_ecb(nfcee_id);
440 
441   if (p_cb == nullptr) {
442     LOG(ERROR) << StringPrintf("Bad ee_handle");
443     status = NFA_STATUS_INVALID_PARAM;
444   } else {
445     p_msg = (tNFA_EE_API_SET_PROTO_CFG*)GKI_getbuf(
446         sizeof(tNFA_EE_API_SET_PROTO_CFG));
447     if (p_msg != nullptr) {
448       p_msg->hdr.event = NFA_EE_API_SET_PROTO_CFG_EVT;
449       p_msg->nfcee_id = nfcee_id;
450       p_msg->p_cb = p_cb;
451       p_msg->protocols_switch_on = protocols_switch_on;
452       p_msg->protocols_switch_off = protocols_switch_off;
453       p_msg->protocols_battery_off = protocols_battery_off;
454       p_msg->protocols_screen_lock = protocols_screen_lock;
455       p_msg->protocols_screen_off = protocols_screen_off;
456       p_msg->protocols_screen_off_lock = protocols_screen_off_lock;
457 
458       nfa_sys_sendmsg(p_msg);
459 
460       status = NFA_STATUS_OK;
461     }
462   }
463 
464   return status;
465 }
466 
467 /*******************************************************************************
468 **
469 ** Function         NFA_EeClearDefaultProtoRouting
470 **
471 ** Description      This function is called to remove the default routing based
472 **                  on RF technology in the listen mode routing table for the
473 **                  given ee_handle. The status of this operation is reported
474 **                  as the NFA_EE_CLEAR_TECH_CFG_EVT.
475 **
476 ** Note:            If RF discovery is started,
477 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
478 **                  happen before calling this function
479 **
480 ** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
481 **                  function to change the listen mode routing is called.
482 **
483 ** Returns          NFA_STATUS_OK if successfully initiated
484 **                  NFA_STATUS_FAILED otherwise
485 **                  NFA_STATUS_INVALID_PARAM If bad parameter
486 **
487 *******************************************************************************/
NFA_EeClearDefaultProtoRouting(tNFA_HANDLE ee_handle,tNFA_PROTOCOL_MASK clear_protocol)488 tNFA_STATUS NFA_EeClearDefaultProtoRouting(tNFA_HANDLE ee_handle,
489                                            tNFA_PROTOCOL_MASK clear_protocol) {
490   tNFA_EE_API_SET_PROTO_CFG* p_msg;
491   tNFA_STATUS status = NFA_STATUS_FAILED;
492   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
493   tNFA_EE_ECB* p_cb;
494 
495   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
496       "handle:<0x%x>clear protocol_mask:<0x%x>", ee_handle, clear_protocol);
497   if (!clear_protocol) {
498     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("nothing to clear");
499     status = NFA_STATUS_OK;
500     return status;
501   }
502 
503   p_cb = nfa_ee_find_ecb(nfcee_id);
504 
505   if (p_cb == nullptr) {
506     LOG(ERROR) << StringPrintf("Bad ee_handle");
507     status = NFA_STATUS_INVALID_PARAM;
508   } else {
509     p_msg = (tNFA_EE_API_SET_PROTO_CFG*)GKI_getbuf(
510         sizeof(tNFA_EE_API_SET_PROTO_CFG));
511     if (p_msg != nullptr) {
512       p_msg->hdr.event = NFA_EE_API_CLEAR_PROTO_CFG_EVT;
513       p_msg->nfcee_id = nfcee_id;
514       p_msg->p_cb = p_cb;
515       p_msg->protocols_switch_on = clear_protocol;
516       p_msg->protocols_switch_off = clear_protocol;
517       p_msg->protocols_battery_off = clear_protocol;
518       p_msg->protocols_screen_lock = clear_protocol;
519       p_msg->protocols_screen_off = clear_protocol;
520       p_msg->protocols_screen_off_lock = clear_protocol;
521 
522       nfa_sys_sendmsg(p_msg);
523 
524       status = NFA_STATUS_OK;
525     }
526   }
527 
528   return status;
529 }
530 
531 /*******************************************************************************
532 **
533 ** Function         NFA_EeAddAidRouting
534 **
535 ** Description      This function is called to add an AID entry in the
536 **                  listen mode routing table in NFCC. The status of this
537 **                  operation is reported as the NFA_EE_ADD_AID_EVT.
538 **
539 ** Note:            If RF discovery is started,
540 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
541 **                  happen before calling this function
542 **
543 ** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
544 **                  function to change the listen mode routing is called.
545 **
546 ** Returns          NFA_STATUS_OK if successfully initiated
547 **                  NFA_STATUS_FAILED otherwise
548 **                  NFA_STATUS_INVALID_PARAM If bad parameter
549 **
550 *******************************************************************************/
NFA_EeAddAidRouting(tNFA_HANDLE ee_handle,uint8_t aid_len,uint8_t * p_aid,tNFA_EE_PWR_STATE power_state,uint8_t aidInfo)551 tNFA_STATUS NFA_EeAddAidRouting(tNFA_HANDLE ee_handle, uint8_t aid_len,
552                                 uint8_t* p_aid, tNFA_EE_PWR_STATE power_state,
553                                 uint8_t aidInfo) {
554   tNFA_EE_API_ADD_AID* p_msg;
555   tNFA_STATUS status = NFA_STATUS_FAILED;
556   uint16_t size = sizeof(tNFA_EE_API_ADD_AID) + aid_len;
557   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
558   tNFA_EE_ECB* p_cb;
559 
560   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:<0x%x>", ee_handle);
561   p_cb = nfa_ee_find_ecb(nfcee_id);
562 
563   /* validate parameters - make sure the AID is in valid length range */
564   if ((p_cb == nullptr) ||
565       ((NFA_GetNCIVersion() == NCI_VERSION_2_0) && (aid_len != 0) &&
566        (p_aid == nullptr)) ||
567       ((NFA_GetNCIVersion() != NCI_VERSION_2_0) &&
568        ((aid_len == 0) || (p_aid == nullptr) || (aid_len < NFA_MIN_AID_LEN))) ||
569       (aid_len > NFA_MAX_AID_LEN)) {
570     LOG(ERROR) << StringPrintf("Bad ee_handle or AID (len=%d)", aid_len);
571     status = NFA_STATUS_INVALID_PARAM;
572   } else {
573     p_msg = (tNFA_EE_API_ADD_AID*)GKI_getbuf(size);
574     if (p_msg != nullptr) {
575       if (p_aid != nullptr)
576         DLOG_IF(INFO, nfc_debug_enabled)
577             << StringPrintf("aid:<%02x%02x>", p_aid[0], p_aid[1]);
578       p_msg->hdr.event = NFA_EE_API_ADD_AID_EVT;
579       p_msg->nfcee_id = nfcee_id;
580       p_msg->p_cb = p_cb;
581       p_msg->aid_len = aid_len;
582       p_msg->power_state = power_state;
583       p_msg->p_aid = (uint8_t*)(p_msg + 1);
584       p_msg->aidInfo = aidInfo;
585       if (p_aid != nullptr) memcpy(p_msg->p_aid, p_aid, aid_len);
586 
587       nfa_sys_sendmsg(p_msg);
588 
589       status = NFA_STATUS_OK;
590     }
591   }
592 
593   return status;
594 }
595 
596 /*******************************************************************************
597 **
598 ** Function         NFA_EeRemoveAidRouting
599 **
600 ** Description      This function is called to remove the given AID entry from
601 **                  the listen mode routing table. If the entry configures VS,
602 **                  it is also removed. The status of this operation is reported
603 **                  as the NFA_EE_REMOVE_AID_EVT.
604 **
605 ** Note:            If RF discovery is started,
606 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
607 **                  happen before calling this function
608 **
609 ** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
610 **                  function to change the listen mode routing is called.
611 **
612 ** Returns          NFA_STATUS_OK if successfully initiated
613 **                  NFA_STATUS_FAILED otherwise
614 **                  NFA_STATUS_INVALID_PARAM If bad parameter
615 **
616 *******************************************************************************/
NFA_EeRemoveAidRouting(uint8_t aid_len,uint8_t * p_aid)617 tNFA_STATUS NFA_EeRemoveAidRouting(uint8_t aid_len, uint8_t* p_aid) {
618   tNFA_EE_API_REMOVE_AID* p_msg;
619   tNFA_STATUS status = NFA_STATUS_FAILED;
620   uint16_t size = sizeof(tNFA_EE_API_REMOVE_AID) + aid_len;
621 
622   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
623   if (((NFA_GetNCIVersion() == NCI_VERSION_2_0) && (aid_len != 0) &&
624        (p_aid == nullptr)) ||
625       ((NFA_GetNCIVersion() != NCI_VERSION_2_0) &&
626        ((aid_len == 0) || (p_aid == nullptr) || (aid_len < NFA_MIN_AID_LEN))) ||
627       (aid_len > NFA_MAX_AID_LEN)) {
628     LOG(ERROR) << StringPrintf("Bad AID");
629     status = NFA_STATUS_INVALID_PARAM;
630   } else {
631     p_msg = (tNFA_EE_API_REMOVE_AID*)GKI_getbuf(size);
632     if (p_msg != nullptr) {
633       p_msg->hdr.event = NFA_EE_API_REMOVE_AID_EVT;
634       p_msg->aid_len = aid_len;
635       p_msg->p_aid = (uint8_t*)(p_msg + 1);
636       memcpy(p_msg->p_aid, p_aid, aid_len);
637 
638       nfa_sys_sendmsg(p_msg);
639 
640       status = NFA_STATUS_OK;
641     }
642   }
643 
644   return status;
645 }
646 
647 /*******************************************************************************
648 **
649 ** Function         NFA_EeAddSystemCodeRouting
650 **
651 ** Description      This function is called to add an system code entry in the
652 **                  listen mode routing table in NFCC. The status of this
653 **                  operation is reported as the NFA_EE_ADD_SYSCODE_EVT.
654 **
655 ** Note:            If RF discovery is started,
656 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
657 **                  happen before calling this function
658 **
659 ** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
660 **                  function to change the listen mode routing is called.
661 **
662 ** Returns          NFA_STATUS_OK if successfully initiated
663 **                  NFA_STATUS_FAILED otherwise
664 **                  NFA_STATUS_INVALID_PARAM If bad parameter
665 **
666 *******************************************************************************/
NFA_EeAddSystemCodeRouting(uint16_t systemcode,tNFA_HANDLE ee_handle,tNFA_EE_PWR_STATE power_state)667 tNFA_STATUS NFA_EeAddSystemCodeRouting(uint16_t systemcode,
668                                        tNFA_HANDLE ee_handle,
669                                        tNFA_EE_PWR_STATE power_state) {
670   tNFA_STATUS status = NFA_STATUS_FAILED;
671   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
672   DLOG_IF(INFO, nfc_debug_enabled)
673       << StringPrintf("NFA_EeAddSystemCodeRouting(): handle:<0x%x>", ee_handle);
674   tNFA_EE_ECB* p_cb = nfa_ee_find_ecb(nfcee_id);
675 
676   if (p_cb == nullptr || systemcode == 0) {
677     LOG(ERROR) << StringPrintf("Bad ee_handle or System Code");
678     status = NFA_STATUS_INVALID_PARAM;
679   } else if ((NFA_GetNCIVersion() != NCI_VERSION_2_0) &&
680              (nfc_cb.isScbrSupported == false)) {
681     LOG(ERROR) << StringPrintf("Invalid NCI Version/SCBR not supported");
682     status = NFA_STATUS_NOT_SUPPORTED;
683   } else {
684     tNFA_EE_API_ADD_SYSCODE* p_msg =
685         (tNFA_EE_API_ADD_SYSCODE*)GKI_getbuf(sizeof(tNFA_EE_API_ADD_SYSCODE));
686     if (p_msg != nullptr) {
687       p_msg->hdr.event = NFA_EE_API_ADD_SYSCODE_EVT;
688       p_msg->power_state = power_state;
689       p_msg->nfcee_id = nfcee_id;
690       p_msg->p_cb = p_cb;
691       // adjust endianness of syscode
692       p_msg->syscode = (systemcode & 0x00FF) << 8 | (systemcode & 0xFF00) >> 8;
693       nfa_sys_sendmsg(p_msg);
694       status = NFA_STATUS_OK;
695     }
696   }
697   return status;
698 }
699 
700 /*******************************************************************************
701 **
702 ** Function         NFA_EeRemoveSystemCodeRouting
703 **
704 ** Description      This function is called to remove the given System Code
705 **                  based entry from the listen mode routing table. The status
706 **                  of this operation is reported as the
707 **                  NFA_EE_REMOVE_SYSCODE_EVT.
708 **
709 ** Note:            If RF discovery is started,
710 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
711 **                  happen before calling this function
712 **
713 ** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
714 **                  function to change the listen mode routing is called.
715 **
716 ** Returns          NFA_STATUS_OK if successfully initiated
717 **                  NFA_STATUS_FAILED otherwise
718 **                  NFA_STATUS_INVALID_PARAM If bad parameter
719 **
720 *******************************************************************************/
NFA_EeRemoveSystemCodeRouting(uint16_t systemcode)721 tNFA_STATUS NFA_EeRemoveSystemCodeRouting(uint16_t systemcode) {
722   tNFA_STATUS status = NFA_STATUS_FAILED;
723 
724   if (systemcode == 0) {
725     LOG(ERROR) << "Bad ee_handle or System Code";
726     status = NFA_STATUS_INVALID_PARAM;
727   } else if ((NFA_GetNCIVersion() != NCI_VERSION_2_0) &&
728              (nfc_cb.isScbrSupported == false)) {
729     LOG(ERROR) << "Invalid NCI Version/SCBR Not supported";
730     status = NFA_STATUS_NOT_SUPPORTED;
731   } else {
732     tNFA_EE_API_REMOVE_SYSCODE* p_msg = (tNFA_EE_API_REMOVE_SYSCODE*)GKI_getbuf(
733         sizeof(tNFA_EE_API_REMOVE_SYSCODE));
734     if (p_msg != nullptr) {
735       p_msg->hdr.event = NFA_EE_API_REMOVE_SYSCODE_EVT;
736       p_msg->syscode = (systemcode & 0x00FF) << 8 | (systemcode & 0xFF00) >> 8;
737       nfa_sys_sendmsg(p_msg);
738       status = NFA_STATUS_OK;
739     }
740   }
741   return status;
742 }
743 
744 /*******************************************************************************
745 **
746 ** Function         NFA_GetAidTableSize
747 **
748 ** Description      This function is called to get the Maximum AID routing table
749 *size.
750 **
751 ** Returns          AID routing table maximum size
752 **
753 *******************************************************************************/
NFA_GetAidTableSize()754 uint16_t NFA_GetAidTableSize() { return nfa_ee_find_max_aid_cfg_len(); }
755 
756 /*******************************************************************************
757 **
758 ** Function         NFA_EeGetLmrtRemainingSize
759 **
760 ** Description      This function is called to get remaining size of the
761 **                  Listen Mode Routing Table.
762 **                  The remaining size is reported in NFA_EE_REMAINING_SIZE_EVT
763 **
764 ** Returns          NFA_STATUS_OK if successfully initiated
765 **                  NFA_STATUS_FAILED otherwise
766 **
767 *******************************************************************************/
NFA_EeGetLmrtRemainingSize(void)768 tNFA_STATUS NFA_EeGetLmrtRemainingSize(void) {
769   tNFA_EE_API_LMRT_SIZE* p_msg;
770   tNFA_STATUS status = NFA_STATUS_FAILED;
771 
772   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
773   p_msg = (tNFA_EE_API_LMRT_SIZE*)GKI_getbuf(sizeof(tNFA_EE_API_LMRT_SIZE));
774   if (p_msg != nullptr) {
775     p_msg->event = NFA_EE_API_LMRT_SIZE_EVT;
776     nfa_sys_sendmsg(p_msg);
777     status = NFA_STATUS_OK;
778   }
779 
780   return status;
781 }
782 
783 /******************************************************************************
784 **
785 ** Function         NFA_EeUpdateNow
786 **
787 ** Description      This function is called to send the current listen mode
788 **                  routing table and VS configuration to the NFCC (without
789 **                  waiting for NFA_EE_ROUT_TIMEOUT_VAL).
790 **
791 **                  The status of this operation is
792 **                  reported with the NFA_EE_UPDATED_EVT.
793 **
794 ** Returns          NFA_STATUS_OK if successfully initiated
795 **                  NFA_STATUS_SEMANTIC_ERROR is update is currently in progress
796 **                  NFA_STATUS_FAILED otherwise
797 **
798 *******************************************************************************/
NFA_EeUpdateNow(void)799 tNFA_STATUS NFA_EeUpdateNow(void) {
800   NFC_HDR* p_msg;
801   tNFA_STATUS status = NFA_STATUS_FAILED;
802 
803   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
804   if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) {
805     LOG(ERROR) << StringPrintf("update in progress");
806     status = NFA_STATUS_SEMANTIC_ERROR;
807   } else {
808     p_msg = (NFC_HDR*)GKI_getbuf(NFC_HDR_SIZE);
809     if (p_msg != nullptr) {
810       p_msg->event = NFA_EE_API_UPDATE_NOW_EVT;
811 
812       nfa_sys_sendmsg(p_msg);
813 
814       status = NFA_STATUS_OK;
815     }
816   }
817 
818   return status;
819 }
820 
821 /*******************************************************************************
822 **
823 ** Function         NFA_EeConnect
824 **
825 ** Description      Open connection to an NFCEE attached to the NFCC
826 **
827 **                  The status of this operation is
828 **                  reported with the NFA_EE_CONNECT_EVT.
829 **
830 ** Returns          NFA_STATUS_OK if successfully initiated
831 **                  NFA_STATUS_FAILED otherwise
832 **                  NFA_STATUS_INVALID_PARAM If bad parameter
833 **
834 *******************************************************************************/
NFA_EeConnect(tNFA_HANDLE ee_handle,uint8_t ee_interface,tNFA_EE_CBACK * p_cback)835 tNFA_STATUS NFA_EeConnect(tNFA_HANDLE ee_handle, uint8_t ee_interface,
836                           tNFA_EE_CBACK* p_cback) {
837   tNFA_EE_API_CONNECT* p_msg;
838   tNFA_STATUS status = NFA_STATUS_FAILED;
839   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
840   tNFA_EE_ECB* p_cb;
841 
842   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
843       "handle:<0x%x> ee_interface:0x%x", ee_handle, ee_interface);
844   p_cb = nfa_ee_find_ecb(nfcee_id);
845 
846   if ((p_cb == nullptr) || (p_cback == nullptr)) {
847     LOG(ERROR) << StringPrintf("Bad ee_handle or NULL callback function");
848     status = NFA_STATUS_INVALID_PARAM;
849   } else {
850     p_msg = (tNFA_EE_API_CONNECT*)GKI_getbuf(sizeof(tNFA_EE_API_CONNECT));
851     if (p_msg != nullptr) {
852       p_msg->hdr.event = NFA_EE_API_CONNECT_EVT;
853       p_msg->nfcee_id = nfcee_id;
854       p_msg->p_cb = p_cb;
855       p_msg->ee_interface = ee_interface;
856       p_msg->p_cback = p_cback;
857 
858       nfa_sys_sendmsg(p_msg);
859 
860       status = NFA_STATUS_OK;
861     }
862   }
863 
864   return status;
865 }
866 
867 /*******************************************************************************
868 **
869 ** Function         NFA_EeSendData
870 **
871 ** Description      Send data to the given NFCEE.
872 **                  This function shall be called after NFA_EE_CONNECT_EVT is
873 **                  reported and before NFA_EeDisconnect is called on the given
874 **                  ee_handle.
875 **
876 ** Returns          NFA_STATUS_OK if successfully initiated
877 **                  NFA_STATUS_FAILED otherwise
878 **                  NFA_STATUS_INVALID_PARAM If bad parameter
879 **
880 *******************************************************************************/
NFA_EeSendData(tNFA_HANDLE ee_handle,uint16_t data_len,uint8_t * p_data)881 tNFA_STATUS NFA_EeSendData(tNFA_HANDLE ee_handle, uint16_t data_len,
882                            uint8_t* p_data) {
883   tNFA_EE_API_SEND_DATA* p_msg;
884   tNFA_STATUS status = NFA_STATUS_FAILED;
885   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
886   tNFA_EE_ECB* p_cb;
887 
888   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:<0x%x>", ee_handle);
889 
890   p_cb = nfa_ee_find_ecb(nfcee_id);
891 
892   if ((p_cb == nullptr) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN) ||
893       (p_data == nullptr)) {
894     LOG(ERROR) << StringPrintf("Bad ee_handle or NULL data");
895     status = NFA_STATUS_INVALID_PARAM;
896   } else {
897     p_msg = (tNFA_EE_API_SEND_DATA*)GKI_getbuf(
898         (uint16_t)(sizeof(tNFA_EE_API_SEND_DATA) + data_len));
899     if (p_msg != nullptr) {
900       p_msg->hdr.event = NFA_EE_API_SEND_DATA_EVT;
901       p_msg->nfcee_id = nfcee_id;
902       p_msg->p_cb = p_cb;
903       p_msg->data_len = data_len;
904       p_msg->p_data = (uint8_t*)(p_msg + 1);
905       memcpy(p_msg->p_data, p_data, data_len);
906 
907       nfa_sys_sendmsg(p_msg);
908 
909       status = NFA_STATUS_OK;
910     }
911   }
912 
913   return status;
914 }
915 
916 /*******************************************************************************
917 **
918 ** Function         NFA_EeDisconnect
919 **
920 ** Description      Disconnect (if a connection is currently open) from an
921 **                  NFCEE interface. The result of this operation is reported
922 **                  with the NFA_EE_DISCONNECT_EVT.
923 **
924 ** Returns          NFA_STATUS_OK if successfully initiated
925 **                  NFA_STATUS_FAILED otherwise
926 **                  NFA_STATUS_INVALID_PARAM If bad parameter
927 **
928 *******************************************************************************/
NFA_EeDisconnect(tNFA_HANDLE ee_handle)929 tNFA_STATUS NFA_EeDisconnect(tNFA_HANDLE ee_handle) {
930   tNFA_EE_API_DISCONNECT* p_msg;
931   tNFA_STATUS status = NFA_STATUS_FAILED;
932   uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
933   tNFA_EE_ECB* p_cb;
934 
935   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:<0x%x>", ee_handle);
936   p_cb = nfa_ee_find_ecb(nfcee_id);
937 
938   if ((p_cb == nullptr) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN)) {
939     LOG(ERROR) << StringPrintf("Bad ee_handle");
940     status = NFA_STATUS_INVALID_PARAM;
941   } else {
942     p_msg = (tNFA_EE_API_DISCONNECT*)GKI_getbuf(sizeof(tNFA_EE_API_DISCONNECT));
943     if (p_msg != nullptr) {
944       p_msg->hdr.event = NFA_EE_API_DISCONNECT_EVT;
945       p_msg->nfcee_id = nfcee_id;
946       p_msg->p_cb = p_cb;
947 
948       nfa_sys_sendmsg(p_msg);
949 
950       status = NFA_STATUS_OK;
951     }
952   }
953 
954   return status;
955 }
956