summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Chu <evanchu@broadcom.com>2013-09-10 10:54:20 +0200
committerMartijn Coenen <maco@google.com>2013-09-10 12:11:29 +0200
commit1ba9dcccf5b342bd74a2f8213b7ed3be78b9db44 (patch)
tree5a03d7e0a8e4cdfd78b44eebf6a6415c469678ec
parent67aef6c6c6f6bc7b8364b97949e874b9dc7175bc (diff)
downloadlibnfc-nci-android-4.4_r1.1.0.1.tar.gz
Found when using reader mode APIs: control is accidentally granted to the HAL, causing us to leak command buffers. Also: - Prevent multiple calls to NFC_Deactivate() - Proper handling of congestion in P2P Bug: 10360259 Change-Id: Ia52a948f46f8668cde5b135bd073f175cdd434f5
-rw-r--r--src/nfa/dm/nfa_dm_discover.c2
-rw-r--r--src/nfc/int/nfc_int.h1
-rw-r--r--src/nfc/llcp/llcp_dlc.c11
-rw-r--r--src/nfc/nfc/nfc_main.c8
-rw-r--r--src/nfc/nfc/nfc_ncif.c3
5 files changed, 17 insertions, 8 deletions
diff --git a/src/nfa/dm/nfa_dm_discover.c b/src/nfa/dm/nfa_dm_discover.c
index 9a96409..10d019f 100644
--- a/src/nfa/dm/nfa_dm_discover.c
+++ b/src/nfa/dm/nfa_dm_discover.c
@@ -2306,7 +2306,7 @@ static void nfa_dm_disc_sm_poll_active (tNFA_DM_RF_DISC_SM_EVENT event,
if ( (!old_sleep_wakeup_flag)
||(!nfa_dm_cb.disc_cb.deact_pending) )
{
- NFC_Deactivate (NFC_DEACTIVATE_TYPE_DISCOVERY);
+ nfa_dm_send_deactivate_cmd (NFA_DEACTIVATE_TYPE_DISCOVERY);
}
break;
diff --git a/src/nfc/int/nfc_int.h b/src/nfc/int/nfc_int.h
index ea7ed03..3c5fe59 100644
--- a/src/nfc/int/nfc_int.h
+++ b/src/nfc/int/nfc_int.h
@@ -89,6 +89,7 @@ typedef UINT8 tNFC_STATE;
#define NFC_FL_CONTROL_REQUESTED 0x0010 /* HAL requested control on NCI command window */
#define NFC_FL_CONTROL_GRANTED 0x0020 /* NCI command window is on the HAL side */
#define NFC_FL_DISCOVER_PENDING 0x0040 /* NCI command window is on the HAL side */
+#define NFC_FL_HAL_REQUESTED 0x0080 /* NFC_FL_CONTROL_REQUESTED on HAL request */
#define NFC_PEND_CONN_ID 0xFE
#define NFC_CONN_ID_INT_MASK 0xF0
diff --git a/src/nfc/llcp/llcp_dlc.c b/src/nfc/llcp/llcp_dlc.c
index a61b841..3e65077 100644
--- a/src/nfc/llcp/llcp_dlc.c
+++ b/src/nfc/llcp/llcp_dlc.c
@@ -1079,6 +1079,7 @@ static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT1
tLLCP_DLCB *p_dlcb;
BOOLEAN flush = TRUE;
tLLCP_SAP_CBACK_DATA cback_data;
+ BOOLEAN old_remote_busy;
LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
@@ -1118,11 +1119,12 @@ static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT1
p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
#endif
-
+ old_remote_busy = p_dlcb->remote_busy;
if (ptype == LLCP_PDU_RNR_TYPE)
{
+ p_dlcb->remote_busy = TRUE;
/* if upper layer hasn't get congestion started notification */
- if ( (!p_dlcb->remote_busy)
+ if ( (!old_remote_busy)
&&(!p_dlcb->is_tx_congested) )
{
LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
@@ -1137,12 +1139,12 @@ static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT1
(*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
}
- p_dlcb->remote_busy = TRUE;
}
else
{
+ p_dlcb->remote_busy = FALSE;
/* if upper layer hasn't get congestion ended notification and data link is not congested */
- if ( (p_dlcb->remote_busy)
+ if ( (old_remote_busy)
&&(!p_dlcb->is_tx_congested) )
{
LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
@@ -1157,7 +1159,6 @@ static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT1
(*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
}
- p_dlcb->remote_busy = FALSE;
}
/* check flag to send DISC when tx queue is empty */
diff --git a/src/nfc/nfc/nfc_main.c b/src/nfc/nfc/nfc_main.c
index d88c78e..261080a 100644
--- a/src/nfc/nfc/nfc_main.c
+++ b/src/nfc/nfc/nfc_main.c
@@ -326,7 +326,7 @@ void nfc_gen_cleanup (void)
nfc_cb.p_disc_pending = NULL;
}
- nfc_cb.flags &= ~(NFC_FL_CONTROL_REQUESTED|NFC_FL_CONTROL_GRANTED);
+ nfc_cb.flags &= ~(NFC_FL_CONTROL_REQUESTED | NFC_FL_CONTROL_GRANTED | NFC_FL_HAL_REQUESTED);
nfc_stop_timer (&nfc_cb.deactivate_timer);
@@ -438,6 +438,7 @@ void nfc_main_handle_hal_evt (tNFC_HAL_EVT_MSG *p_msg)
case HAL_NFC_REQUEST_CONTROL_EVT:
nfc_cb.flags |= NFC_FL_CONTROL_REQUESTED;
+ nfc_cb.flags |= NFC_FL_HAL_REQUESTED;
nfc_ncif_check_cmd_queue (NULL);
break;
@@ -1147,6 +1148,11 @@ tNFC_STATUS NFC_Deactivate (tNFC_DEACT_TYPE deactivate_type)
{
/* the HAL pre-discover is still active - clear the pending flag */
nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+ if (!(nfc_cb.flags & NFC_FL_HAL_REQUESTED))
+ {
+ /* if HAL did not request for control, clear this bit now */
+ nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
+ }
GKI_freebuf (nfc_cb.p_disc_pending);
nfc_cb.p_disc_pending = NULL;
return NFC_STATUS_OK;
diff --git a/src/nfc/nfc/nfc_ncif.c b/src/nfc/nfc/nfc_ncif.c
index e42664d..c5683a0 100644
--- a/src/nfc/nfc/nfc_ncif.c
+++ b/src/nfc/nfc/nfc_ncif.c
@@ -321,9 +321,10 @@ void nfc_ncif_check_cmd_queue (BT_HDR *p_buf)
nfc_cb.p_disc_pending = NULL;
}
}
- else
+ else if (nfc_cb.flags & NFC_FL_HAL_REQUESTED)
{
/* grant the control to HAL */
+ nfc_cb.flags &= ~NFC_FL_HAL_REQUESTED;
nfc_cb.flags |= NFC_FL_CONTROL_GRANTED;
nfc_cb.nci_cmd_window = 0;
nfc_cb.p_hal->control_granted ();