diff options
author | Sherry Smith <sherrys@broadcom.com> | 2013-12-02 15:44:52 -0800 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2014-05-19 13:28:24 -0700 |
commit | 43ef645f118877526ae57eebe35229eb52492211 (patch) | |
tree | 288b1ba31ab1732b7e9518f04536701ea107f0ef | |
parent | f23dcad2c02e3e8d08fe9bbef61776d579b5cb49 (diff) | |
download | libnfc-nci-43ef645f118877526ae57eebe35229eb52492211.tar.gz |
Verify the routing table can hold the new routing entry before adding it.
Change-Id: I5731b9426d0db11287a6da35784042be611a363e
-rw-r--r-- | src/nfa/ee/nfa_ee_act.c | 220 | ||||
-rw-r--r-- | src/nfa/int/nfa_ee_int.h | 2 |
2 files changed, 200 insertions, 22 deletions
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c index 8bd2bc1..ddded01 100644 --- a/src/nfa/ee/nfa_ee_act.c +++ b/src/nfa/ee/nfa_ee_act.c @@ -112,6 +112,126 @@ static void nfa_ee_trace_aid (char *p_str, UINT8 id, UINT8 aid_len, UINT8 *p) NFA_TRACE_DEBUG4 ("%s id:0x%x len=%d aid:%s", p_str, id, aid_len, buff); } + +/******************************************************************************* +** +** Function nfa_ee_update_route_size +** +** Description Update the size required for technology and protocol routing +** of the given NFCEE ID. +** +** Returns void +** +*******************************************************************************/ +static void nfa_ee_update_route_size(tNFA_EE_ECB *p_cb) +{ + int xx; + UINT8 power_cfg = 0; + + p_cb->size_mask = 0; + /* add the Technology based routing */ + for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) + { + 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) + { + /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (techonogy) */ + p_cb->size_mask += 5; + } + } + + /* add the Protocol based routing */ + for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) + { + 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) + { + /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (protocol) */ + p_cb->size_mask += 5; + } + } +} + +/******************************************************************************* +** +** Function nfa_ee_update_route_aid_size +** +** Description Update the size required for AID routing +** of the given NFCEE ID. +** +** Returns void +** +*******************************************************************************/ +static void nfa_ee_update_route_aid_size(tNFA_EE_ECB *p_cb) +{ + UINT8 *pa, len; + int start_offset; + int xx; + + p_cb->size_aid = 0; + if (p_cb->aid_entries) + { + start_offset = 0; + for (xx = 0; xx < p_cb->aid_entries; xx++) + { + /* add one AID entry */ + if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) + { + pa = &p_cb->aid_cfg[start_offset]; + pa ++; /* EMV tag */ + len = *pa++; /* aid_len */ + /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */ + p_cb->size_aid += 4; + p_cb->size_aid += len; + } + start_offset += p_cb->aid_len[xx]; + } + } +} + +/******************************************************************************* +** +** Function nfa_ee_total_lmrt_size +** +** Description the total listen mode routing table size +** +** Returns UINT16 +** +*******************************************************************************/ +static UINT16 nfa_ee_total_lmrt_size(void) +{ + int xx; + UINT16 lmrt_size = 0; + tNFA_EE_ECB *p_cb; + + p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH]; + lmrt_size += p_cb->size_mask; + lmrt_size += p_cb->size_aid; + p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; + for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) + { + if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) + { + lmrt_size += p_cb->size_mask; + lmrt_size += p_cb->size_aid; + } + } + NFA_TRACE_DEBUG1 ("nfa_ee_total_lmrt_size size:%d", lmrt_size); + return lmrt_size; +} + /******************************************************************************* ** ** Function nfa_ee_conn_cback @@ -411,17 +531,34 @@ void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG *p_data) { tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb; tNFA_EE_CBACK_DATA evt_data = {0}; + tNFA_TECHNOLOGY_MASK old_tech_switch_on = p_cb->tech_switch_on; + tNFA_TECHNOLOGY_MASK old_tech_switch_off = p_cb->tech_switch_off; + tNFA_TECHNOLOGY_MASK old_tech_battery_off = p_cb->tech_battery_off; + UINT8 old_size_mask = p_cb->size_mask; p_cb->tech_switch_on = p_data->set_tech.technologies_switch_on; p_cb->tech_switch_off = p_data->set_tech.technologies_switch_off; p_cb->tech_battery_off = p_data->set_tech.technologies_battery_off; - p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH; - if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off) + nfa_ee_update_route_size(p_cb); + if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) { - /* if any technology in any power mode is configured, mark this entry as configured */ - nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); + NFA_TRACE_ERROR0 ("nfa_ee_api_set_tech_cfg Exceed LMRT size"); + evt_data.status = NFA_STATUS_BUFFER_FULL; + p_cb->tech_switch_on = old_tech_switch_on; + p_cb->tech_switch_off = old_tech_switch_off; + p_cb->tech_battery_off = old_tech_battery_off; + p_cb->size_mask = old_size_mask; + } + else + { + p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH; + if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off) + { + /* if any technology in any power mode is configured, mark this entry as configured */ + nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); + } + nfa_ee_start_timer(); } - nfa_ee_start_timer(); nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data); } @@ -440,17 +577,34 @@ void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG *p_data) { tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb; tNFA_EE_CBACK_DATA evt_data = {0}; + tNFA_PROTOCOL_MASK old_proto_switch_on = p_cb->proto_switch_on; + tNFA_PROTOCOL_MASK old_proto_switch_off = p_cb->proto_switch_off; + tNFA_PROTOCOL_MASK old_proto_battery_off = p_cb->proto_battery_off; + UINT8 old_size_mask = p_cb->size_mask; p_cb->proto_switch_on = p_data->set_proto.protocols_switch_on; p_cb->proto_switch_off = p_data->set_proto.protocols_switch_off; p_cb->proto_battery_off = p_data->set_proto.protocols_battery_off; - p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO; - if (p_cb->proto_switch_on | p_cb->proto_switch_off | p_cb->proto_battery_off) + nfa_ee_update_route_size(p_cb); + if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) { - /* if any protocol in any power mode is configured, mark this entry as configured */ - nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); + NFA_TRACE_ERROR0 ("nfa_ee_api_set_proto_cfg Exceed LMRT size"); + evt_data.status = NFA_STATUS_BUFFER_FULL; + p_cb->proto_switch_on = old_proto_switch_on; + p_cb->proto_switch_off = old_proto_switch_off; + p_cb->proto_battery_off = old_proto_battery_off; + p_cb->size_mask = old_size_mask; + } + else + { + p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO; + if (p_cb->proto_switch_on | p_cb->proto_switch_off | p_cb->proto_battery_off) + { + /* if any protocol in any power mode is configured, mark this entry as configured */ + nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); + } + nfa_ee_start_timer(); } - nfa_ee_start_timer(); nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data); } @@ -474,6 +628,7 @@ void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data) int len, len_needed; tNFA_EE_CBACK_DATA evt_data = {0}; int offset = 0, entry = 0; + UINT16 new_size; nfa_ee_trace_aid ("nfa_ee_api_add_aid", p_cb->nfcee_id, p_add->aid_len, p_add->p_aid); p_chk_cb = nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry); @@ -483,7 +638,17 @@ void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data) if (p_chk_cb == p_cb) { p_cb->aid_rt_info[entry] |= NFA_EE_AE_ROUTE; - p_cb->aid_pwr_cfg[entry] = p_add->power_state; + new_size = nfa_ee_total_lmrt_size(); + if (new_size > NFC_GetLmrtSize()) + { + NFA_TRACE_ERROR1 ("Exceed LMRT size:%d (add ROUTE)", new_size); + evt_data.status = NFA_STATUS_BUFFER_FULL; + p_cb->aid_rt_info[entry] &= ~NFA_EE_AE_ROUTE; + } + else + { + p_cb->aid_pwr_cfg[entry] = p_add->power_state; + } } else { @@ -506,17 +671,26 @@ void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data) } else if (p_cb->aid_entries < NFA_EE_MAX_AID_ENTRIES) { - /* add AID */ - p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state; - p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE; - p = p_cb->aid_cfg + len; - p_start = p; - *p++ = NFA_EE_AID_CFG_TAG_NAME; - *p++ = p_add->aid_len; - memcpy(p, p_add->p_aid, p_add->aid_len); - p += p_add->aid_len; - - p_cb->aid_len[p_cb->aid_entries++] = (UINT8)(p - p_start); + new_size = nfa_ee_total_lmrt_size() + 4 + p_add->aid_len; /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */ + if (new_size > NFC_GetLmrtSize()) + { + NFA_TRACE_ERROR1 ("Exceed LMRT size:%d", new_size); + evt_data.status = NFA_STATUS_BUFFER_FULL; + } + else + { + /* add AID */ + p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state; + p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE; + p = p_cb->aid_cfg + len; + p_start = p; + *p++ = NFA_EE_AID_CFG_TAG_NAME; + *p++ = p_add->aid_len; + memcpy(p, p_add->p_aid, p_add->aid_len); + p += p_add->aid_len; + + p_cb->aid_len[p_cb->aid_entries++] = (UINT8)(p - p_start); + } } else { @@ -530,6 +704,7 @@ void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data) /* mark AID changed */ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID; nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); + nfa_ee_update_route_aid_size(p_cb); nfa_ee_start_timer(); } NFA_TRACE_DEBUG2 ("status:%d ee_cfged:0x%02x ",evt_data.status, nfa_ee_cb.ee_cfged); @@ -586,6 +761,7 @@ void nfa_ee_api_remove_aid(tNFA_EE_MSG *p_data) /* else the last entry, just reduce the aid_entries by 1 */ p_cb->aid_entries--; nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); + nfa_ee_update_route_aid_size(p_cb); nfa_ee_start_timer(); /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */ p_cback = p_cb->p_ee_cback; diff --git a/src/nfa/int/nfa_ee_int.h b/src/nfa/int/nfa_ee_int.h index 3342f19..7d4ba61 100644 --- a/src/nfa/int/nfa_ee_int.h +++ b/src/nfa/int/nfa_ee_int.h @@ -158,6 +158,8 @@ typedef struct tNFA_NFC_PROTOCOL lb_protocol; /* Listen B protocol */ tNFA_NFC_PROTOCOL lf_protocol; /* Listen F protocol */ tNFA_NFC_PROTOCOL lbp_protocol; /* Listen B' protocol */ + UINT8 size_mask; /* the size for technology and protocol routing */ + UINT8 size_aid; /* the size for aid routing */ } tNFA_EE_ECB; /* data type for NFA_EE_API_DISCOVER_EVT */ |