NCI2.0 Ordering of Routing Table
As per NCI 2.0 routing table shall be in the following order
All AID-based Routing Entries (if any)
All APDU Pattern-based Routing Entries (if any)
All System Code-based Routing Entries (if any)
All Protocol-based Routing Entries (if any)
All Technology-based Routing Entries (if any)
Test: compiles.
Change-Id: I997dd2ec294febd8a162426ae317aab6bfa2554f
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c
index 53f9c39..f7f62e8 100644
--- a/src/nfa/ee/nfa_ee_act.c
+++ b/src/nfa/ee/nfa_ee_act.c
@@ -52,6 +52,30 @@
/* the following 2 tables convert the protocol mask in API and control block to
* the command for NFCC */
#define NFA_EE_NUM_PROTO 5
+
+static void add_route_tech_proto_tlv(uint8_t* pp, uint8_t tlv_type,
+ uint8_t nfcee_id, uint8_t pwr_cfg,
+ uint8_t tech_proto) {
+ *pp++ = tlv_type;
+ *pp++ = 3;
+ *pp++ = nfcee_id;
+ *pp++ = pwr_cfg;
+ *pp++ = tech_proto;
+}
+
+static void add_route_aid_tlv(uint8_t* pp, uint8_t* pa, uint8_t nfcee_id,
+ uint8_t pwr_cfg) {
+ pa++; /* EMV tag */
+ uint8_t len = *pa++; /* aid_len */
+ *pp++ = (uint8_t)NFC_ROUTE_TAG_AID;
+ *pp++ = len + 2;
+ *pp++ = nfcee_id;
+ *pp++ = pwr_cfg;
+ /* copy the AID */
+ memcpy(pp, pa, len);
+ pp += len;
+}
+
const uint8_t nfa_ee_proto_mask_list[NFA_EE_NUM_PROTO] = {
NFA_PROTOCOL_MASK_T1T, NFA_PROTOCOL_MASK_T2T, NFA_PROTOCOL_MASK_T3T,
NFA_PROTOCOL_MASK_ISO_DEP, NFA_PROTOCOL_MASK_NFC_DEP};
@@ -62,6 +86,8 @@
static void nfa_ee_report_discover_req_evt(void);
static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data);
+void nfa_ee_check_set_routing(uint16_t new_size, int* p_max_len, uint8_t* p,
+ int* p_cur_offset);
/*******************************************************************************
**
** Function nfa_ee_trace_aid
@@ -200,6 +226,116 @@
return lmrt_size;
}
+static void nfa_ee_add_tech_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
+ uint8_t* p, uint8_t* ps,
+ int* p_cur_offset) {
+ uint8_t num_tlv = *ps;
+
+ /* add the Technology based routing */
+ for (int xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
+ uint8_t power_cfg = 0;
+ if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+ if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+ if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+ if (power_cfg) {
+ add_route_tech_proto_tlv(pp, NFC_ROUTE_TAG_TECH, p_cb->nfcee_id,
+ power_cfg, nfa_ee_tech_list[xx]);
+ num_tlv++;
+ if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+ nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+ }
+ }
+
+ /* update the num_tlv and current offset */
+ uint8_t entry_size = (uint8_t)(pp - p);
+ *p_cur_offset += entry_size;
+ *ps = num_tlv;
+}
+
+static void nfa_ee_add_proto_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
+ uint8_t* p, uint8_t* ps,
+ int* p_cur_offset) {
+ uint8_t num_tlv = *ps;
+
+ /* add the Protocol based routing */
+ for (int xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
+ uint8_t power_cfg = 0;
+ if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+ if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+ if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+ if (power_cfg) {
+ add_route_tech_proto_tlv(pp, NFC_ROUTE_TAG_PROTO, p_cb->nfcee_id,
+ power_cfg, nfa_ee_proto_list[xx]);
+ num_tlv++;
+ if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+ nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+ }
+ }
+
+ /* add NFC-DEP routing to HOST */
+ if (p_cb->nfcee_id == NFC_DH_ID) {
+ add_route_tech_proto_tlv(pp, NFC_ROUTE_TAG_PROTO, NFC_DH_ID,
+ NCI_ROUTE_PWR_STATE_ON, NFC_PROTOCOL_NFC_DEP);
+
+ num_tlv++;
+ NFA_TRACE_DEBUG1(
+ "%s - NFC DEP added for "
+ "DH!!!",
+ __FUNCTION__);
+ }
+ /* update the num_tlv and current offset */
+ uint8_t entry_size = (uint8_t)(pp - p);
+ *p_cur_offset += entry_size;
+ *ps = num_tlv;
+}
+
+static void nfa_ee_add_aid_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
+ uint8_t* p, uint8_t* ps,
+ int* p_cur_offset, int* p_max_len) {
+ uint8_t num_tlv = *ps;
+
+ /* add the AID routing */
+ if (p_cb->aid_entries) {
+ int start_offset = 0;
+ for (int xx = 0; xx < p_cb->aid_entries; xx++) {
+ /* remember the beginning of this AID routing entry, just in case we
+ * need to put it in next command */
+ uint8_t* p_start = pp;
+ /* add one AID entry */
+ if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) {
+ num_tlv++;
+ uint8_t* pa = &p_cb->aid_cfg[start_offset];
+ add_route_aid_tlv(pp, pa, p_cb->nfcee_id, p_cb->aid_pwr_cfg[xx]);
+ }
+ start_offset += p_cb->aid_len[xx];
+ uint8_t new_size = (uint8_t)(pp - p_start);
+ nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
+ if (*ps == 0) {
+ /* just sent routing command, update local */
+ *ps = 1;
+ num_tlv = *ps;
+ *p_cur_offset = new_size;
+ pp = ps + 1;
+ p = pp;
+ memcpy(p, p_start, new_size);
+ pp += new_size;
+ } else {
+ /* add the new entry */
+ *ps = num_tlv;
+ *p_cur_offset += new_size;
+ }
+ }
+ } else {
+ NFA_TRACE_DEBUG1("%s - No AID entries available", __func__);
+ }
+}
+
/*******************************************************************************
**
** Function nfa_ee_conn_cback
@@ -1896,6 +2032,84 @@
return status;
}
+/*******************************************************************************
+**
+** Function nfa_ee_route_add_one_ecb_order
+**
+** Description Add the routing entries for NFCEE/DH in order defined
+**
+** Returns NFA_STATUS_OK, if ok to continue
+**
+*******************************************************************************/
+void nfa_ee_route_add_one_ecb_by_route_order(tNFA_EE_ECB* p_cb, int rout_type,
+ int* p_max_len, bool more,
+ uint8_t* ps, int* p_cur_offset) {
+ nfa_ee_check_set_routing(p_cb->size_mask, p_max_len, ps, p_cur_offset);
+
+ /* use the first byte of the buffer (ps) to keep the num_tlv */
+ uint8_t num_tlv = *ps;
+ NFA_TRACE_DEBUG6(
+ "%s - max_len:%d, cur_offset:%d, more:%d, num_tlv:%d,rout_type:- %d",
+ __FUNCTION__, *p_max_len, *p_cur_offset, more, num_tlv, rout_type);
+ uint8_t* pp = ps + 1 + *p_cur_offset;
+ uint8_t* p = pp;
+ uint16_t tlv_size = (uint8_t)*p_cur_offset;
+
+ switch (rout_type) {
+ case NCI_ROUTE_ORDER_TECHNOLOGY: {
+ nfa_ee_add_tech_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
+ } break;
+
+ case NCI_ROUTE_ORDER_PROTOCOL: {
+ nfa_ee_add_proto_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
+ } break;
+ case NCI_ROUTE_ORDER_AID: {
+ nfa_ee_add_aid_route_to_ecb(p_cb, pp, p, ps, p_cur_offset, p_max_len);
+ } break;
+ default: {
+ NFA_TRACE_DEBUG2("%s - Route type - NA:- %d", __FUNCTION__, rout_type);
+ }
+ }
+
+ /* update the total number of entries */
+ num_tlv = *ps;
+
+ tlv_size = nfa_ee_total_lmrt_size();
+ if (tlv_size) {
+ nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+ }
+ if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) {
+ nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
+ }
+ NFA_TRACE_DEBUG2("ee_cfg_sts:0x%02x lmrt_size:%d", nfa_ee_cb.ee_cfg_sts,
+ tlv_size);
+
+ if (more == false) {
+ /* last entry. update routing table now */
+ if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) {
+ if (tlv_size) {
+ nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING;
+ } else {
+ nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
+ }
+ NFA_TRACE_DEBUG3("%s : set routing num_tlv:%d tlv_size:%d", __FUNCTION__,
+ num_tlv, tlv_size);
+ if (NFC_SetRouting(more, num_tlv, (uint8_t)(*p_cur_offset), ps + 1) ==
+ NFA_STATUS_OK) {
+ nfa_ee_cb.wait_rsp++;
+ }
+ } else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) {
+ if (tlv_size == 0) {
+ nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
+ /* indicated routing is configured to NFCC */
+ nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
+ if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK) {
+ nfa_ee_cb.wait_rsp++;
+ }
+ }
+ }
+ }
+}
/*******************************************************************************
**
@@ -2020,8 +2234,9 @@
tNFA_EE_ECB* p_cb;
uint8_t* p = NULL;
bool more = true;
+ bool check = true;
uint8_t last_active = NFA_EE_INVALID;
- int max_len, len;
+ int max_len;
tNFA_STATUS status = NFA_STATUS_FAILED;
int cur_offset;
uint8_t max_tlv;
@@ -2046,11 +2261,9 @@
}
}
if (last_active == NFA_EE_INVALID) {
- more = false;
+ check = false;
}
- /* add the routing for DH first */
- status = NFA_STATUS_OK;
max_len = NFC_GetLmrtSize();
max_tlv =
(uint8_t)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE) ? NFA_EE_ROUT_MAX_TLV_SIZE
@@ -2058,30 +2271,23 @@
cur_offset = 0;
/* use the first byte of the buffer (p) to keep the num_tlv */
*p = 0;
- status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], &max_len,
- more, p, &cur_offset);
-
- /* add only what is supported by NFCC. report overflow */
- if (status == NFA_STATUS_OK) {
- /* add the routing for NFCEEs */
+ for (int rt = NCI_ROUTE_ORDER_AID; rt <= NCI_ROUTE_ORDER_TECHNOLOGY; rt++) {
+ /* add the routing entries for NFCEEs */
p_cb = &nfa_ee_cb.ecb[0];
- for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++) {
- len = 0;
+ for (xx = 0; (xx < nfa_ee_cb.cur_ee) && check; xx++, p_cb++) {
if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
- NFA_TRACE_DEBUG2("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id,
- last_active);
- if (last_active == p_cb->nfcee_id) more = false;
- status = nfa_ee_route_add_one_ecb(p_cb, &max_len, more, p, &cur_offset);
- if (status != NFA_STATUS_OK) {
- more = false;
- }
+ NFA_TRACE_DEBUG1("%s --add the routing for NFCEEs!!", __func__);
+ nfa_ee_route_add_one_ecb_by_route_order(p_cb, rt, &max_len, more, p,
+ &cur_offset);
}
}
+ if (rt == NCI_ROUTE_ORDER_TECHNOLOGY) more = false;
+ /* add the routing entries for DH */
+ NFA_TRACE_DEBUG1("%s --add the routing for DH!!", __func__);
+ nfa_ee_route_add_one_ecb_by_route_order(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], rt,
+ &max_len, more, p, &cur_offset);
}
- if (status != NFA_STATUS_OK) {
- nfa_ee_report_event(NULL, NFA_EE_ROUT_ERR_EVT,
- (tNFA_EE_CBACK_DATA*)&status);
- }
+
GKI_freebuf(p);
}
diff --git a/src/nfa/int/nfa_ee_int.h b/src/nfa/int/nfa_ee_int.h
index 5017195..61d4a52 100644
--- a/src/nfa/int/nfa_ee_int.h
+++ b/src/nfa/int/nfa_ee_int.h
@@ -427,6 +427,13 @@
tNFA_EE_FLAGS ee_flags; /* flags */
} tNFA_EE_CB;
+/* Order of Routing entries in Routing Table */
+#define NCI_ROUTE_ORDER_AID 0x01 /* AID routing order */
+#define NCI_ROUTE_ORDER_PATTERN 0x02 /* Pattern routing order*/
+#define NCI_ROUTE_ORDER_SYS_CODE 0x03 /* System Code routing order*/
+#define NCI_ROUTE_ORDER_PROTOCOL 0x04 /* Protocol routing order*/
+#define NCI_ROUTE_ORDER_TECHNOLOGY 0x05 /* Technology routing order*/
+
/*****************************************************************************
** External variables
*****************************************************************************/