Merge "ISO-DEP presence check workaround"
diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c
index aa70d79..5c7e0af 100644
--- a/halimpl/pn54x/hal/phNxpNciHal.c
+++ b/halimpl/pn54x/hal/phNxpNciHal.c
@@ -30,6 +30,7 @@
 #define PN547C2_CLOCK_SETTING
 #undef  PN547C2_FACTORY_RESET_DEBUG
 #define CORE_RES_STATUS_BYTE 3
+
 /* Processing of ISO 15693 EOF */
 extern uint8_t icode_send_eof;
 static uint8_t cmd_icode_eof[] = { 0x00, 0x00, 0x00 };
@@ -63,6 +64,8 @@
 
 phNxpNciRfSetting_t phNxpNciRfSet={0,};
 
+phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {0};
+
 /**************** local methods used in this file only ************************/
 static NFCSTATUS phNxpNciHal_fw_download(void);
 static void phNxpNciHal_open_complete(NFCSTATUS status);
@@ -80,9 +83,12 @@
 static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len);
 static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
 static void phNxpNciHal_enable_i2c_fragmentation();
+static NFCSTATUS phNxpNciHal_get_mw_eeprom (void);
+static NFCSTATUS phNxpNciHal_set_mw_eeprom (void);
 NFCSTATUS phNxpNciHal_check_clock_config(void);
 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
 int  check_config_parameter();
+
 /******************************************************************************
  * Function         phNxpNciHal_client_thread
  *
@@ -1030,6 +1036,15 @@
         }
     }
 
+    // Check if firmware download success
+    status = phNxpNciHal_get_mw_eeprom ();
+    if (status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E ("NXP GET MW EEPROM AREA Proprietary Ext failed");
+        retry_core_init_cnt++;
+        goto retry_core_init;
+    }
+
     //
     status = phNxpNciHal_check_clock_config();
     if (status != NFCSTATUS_SUCCESS) {
@@ -1310,6 +1325,12 @@
             return NFCSTATUS_FAILED;
         }
 #endif
+        // Update eeprom value
+        status = phNxpNciHal_set_mw_eeprom ();
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E ("NXP Update MW EEPROM Proprietary Ext failed");
+        }
     }
 
     retlen = 0;
@@ -1877,6 +1898,80 @@
 }
 
 /******************************************************************************
+ * Function         phNxpNciHal_get_mw_eeprom
+ *
+ * Description      This function is called to retreive data in mw eeprom area
+ *
+ * Returns          NFCSTATUS.
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_get_mw_eeprom (void)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint8_t retry_cnt = 0;
+    static uint8_t get_mw_eeprom_cmd[] = { 0x20, 0x03,0x03, 0x01, 0xA0, 0x0F };
+    uint8_t bConfig;
+
+retry_send_ext:
+    if (retry_cnt > 3)
+    {
+        return NFCSTATUS_FAILED;
+    }
+
+    phNxpNciMwEepromArea.isGetEepromArea = TRUE;
+    status = phNxpNciHal_send_ext_cmd (sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
+    if (status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E ("unable to get the mw eeprom data");
+        phNxpNciMwEepromArea.isGetEepromArea = FALSE;
+        retry_cnt++;
+        goto retry_send_ext;
+    }
+    phNxpNciMwEepromArea.isGetEepromArea = FALSE;
+
+    if (phNxpNciMwEepromArea.p_rx_data[12])
+    {
+        fw_download_success = 1;
+    }
+    return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_set_mw_eeprom
+ *
+ * Description      This function is called to update data in mw eeprom area
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_set_mw_eeprom (void)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint8_t retry_cnt = 0;
+    uint8_t set_mw_eeprom_cmd[39] = {0};
+    uint8_t cmd_header[] = { 0x20, 0x02,0x24, 0x01, 0xA0, 0x0F, 0x20 };
+
+    memcpy (set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
+    phNxpNciMwEepromArea.p_rx_data[12] = 0;
+    memcpy (set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data, sizeof(phNxpNciMwEepromArea.p_rx_data));
+
+retry_send_ext:
+    if (retry_cnt > 3)
+    {
+        return NFCSTATUS_FAILED;
+    }
+
+    status = phNxpNciHal_send_ext_cmd (sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
+    if (status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E ("unable to update the mw eeprom data");
+        retry_cnt++;
+        goto retry_send_ext;
+    }
+    return status;
+}
+
+/******************************************************************************
  * Function         phNxpNciHal_set_clock
  *
  * Description      This function is called after successfull download
@@ -2317,7 +2412,7 @@
             }
         }
 
-        if(phNxpNciRfSet.isGetRfSetting)
+        else if(phNxpNciRfSet.isGetRfSetting)
         {
             int i;
             for(i=0; i<* p_len; i++)
@@ -2325,16 +2420,23 @@
                 phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
                 //NXPLOG_NCIHAL_D("%s: response status =0x%x",__FUNCTION__,p_rx_data[i]);
             }
-
+        }
+        else if (phNxpNciMwEepromArea.isGetEepromArea)
+        {
+            int i;
+            for (i = 8; i < *p_len; i++)
+            {
+                phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
+            }
         }
     }
 
-if((p_rx_data[2])&&(config_access == TRUE))
+    if (p_rx_data[2] && (config_access == TRUE))
     {
-        if(p_rx_data[3]!=NFCSTATUS_SUCCESS)
+        if (p_rx_data[3] != NFCSTATUS_SUCCESS)
         {
-            NXPLOG_NCIHAL_W("Invalid Data from config file . Aborting..");
-            phNxpNciHal_close();
+            NXPLOG_NCIHAL_W ("Invalid Data from config file . Aborting..");
+            phNxpNciHal_close ();
         }
     }
 }
diff --git a/halimpl/pn54x/hal/phNxpNciHal.h b/halimpl/pn54x/hal/phNxpNciHal.h
index fa7b637..6c97cd2 100644
--- a/halimpl/pn54x/hal/phNxpNciHal.h
+++ b/halimpl/pn54x/hal/phNxpNciHal.h
@@ -94,6 +94,10 @@
     uint8_t  p_rx_data[20];
 }phNxpNciRfSetting_t;
 
+typedef struct phNxpNciMwEepromArea {
+    bool_t  isGetEepromArea;
+    uint8_t p_rx_data[32];
+} phNxpNciMwEepromArea_t;
 
 typedef enum {
     NFC_FORUM_PROFILE,
diff --git a/src/nfa/dm/nfa_dm_act.c b/src/nfa/dm/nfa_dm_act.c
index 242963f..156b03c 100644
--- a/src/nfa/dm/nfa_dm_act.c
+++ b/src/nfa/dm/nfa_dm_act.c
@@ -1630,6 +1630,11 @@
                 {
                     /* activate LLCP */
                     nfa_p2p_activate_llcp (p_data);
+                    if (nfa_dm_cb.p_activate_ntf)
+                    {
+                        GKI_freebuf (nfa_dm_cb.p_activate_ntf);
+                        nfa_dm_cb.p_activate_ntf = NULL;
+                    }
                 }
                 else
                 {
@@ -1770,8 +1775,18 @@
         /* get length of NFCID and location */
         if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_A)
         {
-            nfcid_len = p_tech_params->param.pa.nfcid1_len;
-            p_nfcid   = p_tech_params->param.pa.nfcid1;
+            if ((p_tech_params->param.pa.nfcid1_len == 0) && (p_params != NULL))
+            {
+                nfcid_len = sizeof(p_params->t1t.uid);
+                p_nfcid   = p_params->t1t.uid;
+                evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1_len = nfcid_len;
+                memcpy (evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1, p_nfcid, nfcid_len);
+            }
+            else
+            {
+                nfcid_len = p_tech_params->param.pa.nfcid1_len;
+                p_nfcid   = p_tech_params->param.pa.nfcid1;
+            }
         }
         else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_B)
         {
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c
index b7561b4..c474eea 100644
--- a/src/nfa/ee/nfa_ee_act.c
+++ b/src/nfa/ee/nfa_ee_act.c
@@ -537,6 +537,16 @@
     tNFA_TECHNOLOGY_MASK    old_tech_battery_off = p_cb->tech_battery_off;
     UINT8                   old_size_mask        = p_cb->size_mask;
 
+    if (   (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))
+    {
+        /* nothing to change */
+        evt_data.status = NFA_STATUS_OK;
+        nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
+        return;
+    }
+
     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;
@@ -583,6 +593,16 @@
     tNFA_PROTOCOL_MASK    old_proto_battery_off = p_cb->proto_battery_off;
     UINT8                   old_size_mask        = p_cb->size_mask;
 
+    if (   (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)  )
+    {
+        /* nothing to change */
+        evt_data.status = NFA_STATUS_OK;
+        nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
+        return;
+    }
+
     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;
@@ -1968,6 +1988,17 @@
         }
     }
 
+    /* add NFC-DEP routing to HOST */
+    if (p_cb->nfcee_id == NFC_DH_ID)
+    {
+        *pp++   = NFC_ROUTE_TAG_PROTO;
+        *pp++   = 3;
+        *pp++   = NFC_DH_ID;
+        *pp++   = NCI_ROUTE_PWR_STATE_ON;
+        *pp++   = NFC_PROTOCOL_NFC_DEP;
+        num_tlv++;
+    }
+
     /* update the num_tlv and current offset */
     entry_size       = (UINT8)(pp - p);
     *p_cur_offset   += entry_size;
diff --git a/src/nfa/rw/nfa_rw_act.c b/src/nfa/rw/nfa_rw_act.c
index 7418ed1..465f457 100644
--- a/src/nfa/rw/nfa_rw_act.c
+++ b/src/nfa/rw/nfa_rw_act.c
@@ -284,6 +284,7 @@
                 conn_evt_data.ndef_detect.cur_size = 0;
                 conn_evt_data.ndef_detect.max_size = 0;
                 conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
+                conn_evt_data.ndef_detect.status   = NFA_STATUS_TIMEOUT;
             }
             else
             {
@@ -557,11 +558,41 @@
 static void nfa_rw_handle_t1t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
 {
     tNFA_CONN_EVT_DATA conn_evt_data;
+    tNFA_TAG_PARAMS tag_params;
+    UINT8 *p_rid_rsp;
+    tNFA_STATUS activation_status;
 
     conn_evt_data.status = p_rw_data->data.status;
     switch (event)
     {
     case RW_T1T_RID_EVT:
+        if (p_rw_data->data.p_data != NULL)
+        {
+            /* Assume the data is just the response byte sequence */
+            p_rid_rsp = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
+            /* Fetch HR from RID response message */
+            STREAM_TO_ARRAY (tag_params.t1t.hr, p_rid_rsp, T1T_HR_LEN);
+            /* Fetch UID0-3 from RID response message */
+            STREAM_TO_ARRAY (tag_params.t1t.uid, p_rid_rsp, T1T_CMD_UID_LEN);
+            GKI_freebuf (p_rw_data->data.p_data);
+            p_rw_data->data.p_data = NULL;
+        }
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+
+        if (p_rw_data->status == NFC_STATUS_TIMEOUT)
+        {
+            activation_status = NFA_STATUS_TIMEOUT;
+        }
+        else
+        {
+            activation_status = NFA_STATUS_OK;
+        }
+
+        nfa_dm_notify_activation_status (activation_status, &tag_params);
+        break;
+
     case RW_T1T_RALL_CPLT_EVT:
     case RW_T1T_READ_CPLT_EVT:
     case RW_T1T_RSEG_CPLT_EVT:
@@ -2584,6 +2615,11 @@
         &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)  )
     {
         /* Type 2 tag is wake up from HALT State */
+        if(nfa_dm_cb.p_activate_ntf != NULL)
+        {
+            GKI_freebuf (nfa_dm_cb.p_activate_ntf);
+            nfa_dm_cb.p_activate_ntf = NULL;
+        }
         NFA_TRACE_DEBUG0("nfa_rw_activate_ntf () - Type 2 tag wake up from HALT State");
         return TRUE;
     }
@@ -2670,6 +2706,9 @@
         /* Retrieve HR and UID fields from activation notification */
         memcpy (tag_params.t1t.hr, p_activate_params->intf_param.intf_param.frame.param, NFA_T1T_HR_LEN);
         memcpy (tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
+        msg.op = NFA_RW_OP_T1T_RID;
+        nfa_rw_handle_op_req ((tNFA_RW_MSG *)&msg);
+        activate_notify = FALSE;                    /* Delay notifying upper layer of NFA_ACTIVATED_EVT until HR0/HR1 is received */
         break;
 
     case NFC_PROTOCOL_T2T:
diff --git a/src/nfc/tags/rw_i93.c b/src/nfc/tags/rw_i93.c
index d77b231..acdbcb7 100644
--- a/src/nfc/tags/rw_i93.c
+++ b/src/nfc/tags/rw_i93.c
@@ -3080,6 +3080,13 @@
         }
         else
         {
+            /* free retry buffer */
+            if (p_i93->p_retry_cmd)
+            {
+                GKI_freebuf (p_i93->p_retry_cmd);
+                p_i93->p_retry_cmd = NULL;
+                p_i93->retry_count = 0;
+            }
             NFC_SetStaticRfCback (NULL);
             p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
         }
diff --git a/src/nfc/tags/rw_t1t.c b/src/nfc/tags/rw_t1t.c
index e7d373e..a7a8001 100644
--- a/src/nfc/tags/rw_t1t.c
+++ b/src/nfc/tags/rw_t1t.c
@@ -295,6 +295,12 @@
         {
             rw_t1t_process_error ();
         }
+        if((p_data != NULL) && (p_data->data.p_data != NULL))
+        {
+            /* Free the response buffer in case of invalid response*/
+            GKI_freebuf((BT_HDR *) (p_data->data.p_data));
+            p_data->data.p_data = NULL;
+        }
         break;
 
     default:
diff --git a/src/nfc/tags/rw_t1t_ndef.c b/src/nfc/tags/rw_t1t_ndef.c
index 29aff77..a6a25b6 100644
--- a/src/nfc/tags/rw_t1t_ndef.c
+++ b/src/nfc/tags/rw_t1t_ndef.c
@@ -2200,7 +2200,7 @@
                     {
                         /* Set/clear lock_attr byte bits based on whether a particular lock bit is set or not
                          * each bit in lock_attr represents one byte in Tag read only attribute */
-                        if (p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx])
+                        if ((p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx]) && (block_count < T1T_BLOCKS_PER_SEGMENT))
                         {
                             p_t1t->lock_attr[block_count] |= 0x01 << bits_covered;
                         }
diff --git a/src/nfc/tags/rw_t2t.c b/src/nfc/tags/rw_t2t.c
index de2de64..e6f5b5b 100644
--- a/src/nfc/tags/rw_t2t.c
+++ b/src/nfc/tags/rw_t2t.c
@@ -346,6 +346,13 @@
         {
             rw_t2t_process_error ();
         }
+        /* Free the response buffer in case of invalid response*/
+        if((p_data != NULL) && (p_data->data.p_data != NULL))
+        {
+            /* Free the response buffer in case of invalid response*/
+            GKI_freebuf((BT_HDR *) (p_data->data.p_data));
+            p_data->data.p_data = NULL;
+        }
         break;
 
     default: