Merge "Extend the NFC product range compatibility"
diff --git a/src/nfc/include/rw_int.h b/src/nfc/include/rw_int.h
index 61f0820..f4027a5 100644
--- a/src/nfc/include/rw_int.h
+++ b/src/nfc/include/rw_int.h
@@ -693,6 +693,13 @@
   RW_I93_STM_M24LR64E_R,             /* STM M24LR64E-R                   */
   RW_I93_STM_ST25DV04K,              /* STM ST25DV04K                    */
   RW_I93_STM_ST25DVHIK,              /* STM ST25DV 16K OR 64K            */
+  RW_I93_ONS_N36RW02,                /* ONS N36RW02                      */
+  RW_I93_ONS_N24RF04,                /* ONS N24RF04                      */
+  RW_I93_ONS_N24RF04E,               /* ONS N24RF04E                     */
+  RW_I93_ONS_N24RF16,                /* ONS N24RF16                      */
+  RW_I93_ONS_N24RF16E,               /* ONS N24RF16E                     */
+  RW_I93_ONS_N24RF64,                /* ONS N24RF64                      */
+  RW_I93_ONS_N24RF64E,               /* ONS N24RF64E                     */
   RW_I93_UNKNOWN_PRODUCT             /* Unknwon product version          */
 };
 
diff --git a/src/nfc/include/tags_defs.h b/src/nfc/include/tags_defs.h
index 23a8f03..4177c78 100644
--- a/src/nfc/include/tags_defs.h
+++ b/src/nfc/include/tags_defs.h
@@ -577,6 +577,7 @@
 #define I93_ICODE_CC_IPREAD_MASK 0x02
 /* More than 2040 bytes are supported in CC[3] */
 #define I93_STM_CC_OVERFLOW_MASK 0x04
+#define I93_ONS_CC_OVERFLOW_MASK 0x04
 
 /* ICODE TLV type */
 #define I93_ICODE_TLV_TYPE_NULL 0x00 /* NULL TLV         */
@@ -591,6 +592,7 @@
 #define I93_UID_IC_MFG_CODE_STM 0x02
 #define I93_UID_IC_MFG_CODE_NXP 0x04
 #define I93_UID_IC_MFG_CODE_TI 0x07
+#define I93_UID_IC_MFG_CODE_ONS 0x67
 
 /* NXP, UID Coding of ICODE type (UID Bit 48-41) */
 /* ICODE SLI, SLIX     */
@@ -656,7 +658,26 @@
  */
 #define I93_IC_REF_STM_ST25DVHIK 0x26
 
+/* ONS, product version (IC manufacturer code) */
+/* IC Reference for N36RW02:  00011010(b), blockSize: 4, numberBlocks: 0x40 */
+#define I93_IC_REF_ONS_N36RW02  0x1A
+/* IC Reference for N24RF04:  00101010(b), blockSize: 4, numberBlocks: 0x80 */
+#define I93_IC_REF_ONS_N24RF04  0x2A
+/* IC Reference for N24RF04E: 00101110(b), blockSize: 4, numberBlocks: 0x80 */
+#define I93_IC_REF_ONS_N24RF04E 0x2E
+/* IC Reference for N24RF16:  01001010(b), blockSize: 4, numberBlocks: 0x200 */
+#define I93_IC_REF_ONS_N24RF16  0x4A
+/* IC Reference for N24RF16E: 01001110(b), blockSize: 4, numberBlocks: 0x200 */
+#define I93_IC_REF_ONS_N24RF16E 0x4E
+/* IC Reference for N24RF64:  01101010(b), blockSize: 4, numberBlocks: 0x800 */
+#define I93_IC_REF_ONS_N24RF64  0x6A
+/* IC Reference for N24RF64E: 01101110(b), blockSize: 4, numberBlocks: 0x800 */
+#define I93_IC_REF_ONS_N24RF64E 0x6E
+
 #define I93_STM_BLOCKS_PER_SECTOR 32
 #define I93_STM_MAX_BLOCKS_PER_READ 32
 
-#endif /* TAGS_DEFS_H */
+#define I93_ONS_BLOCKS_PER_SECTOR 32
+#define I93_ONS_MAX_BLOCKS_PER_READ 32
+
+#endif /* TAGS_DEFS_H */ 
\ No newline at end of file
diff --git a/src/nfc/tags/rw_i93.cc b/src/nfc/tags/rw_i93.cc
index d9be513..6c49db8 100644
--- a/src/nfc/tags/rw_i93.cc
+++ b/src/nfc/tags/rw_i93.cc
@@ -178,6 +178,34 @@
           break;
       }
     }
+  } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_ONS) &&
+             (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
+      switch (p_i93->ic_reference) {
+        case I93_IC_REF_ONS_N36RW02:
+          p_i93->product_version = RW_I93_ONS_N36RW02;
+          break;
+        case I93_IC_REF_ONS_N24RF04:
+          p_i93->product_version = RW_I93_ONS_N24RF04;
+          break;
+        case I93_IC_REF_ONS_N24RF04E:
+          p_i93->product_version = RW_I93_ONS_N24RF04E;
+          break;
+        case RW_I93_ONS_N24RF16:
+          p_i93->product_version = RW_I93_ONS_N24RF16;
+          break;
+        case RW_I93_ONS_N24RF16E:
+          p_i93->product_version = RW_I93_ONS_N24RF16E;
+          break;
+        case RW_I93_ONS_N24RF64:
+          p_i93->product_version = RW_I93_ONS_N24RF64;
+          break;
+        case RW_I93_ONS_N24RF64E:
+          p_i93->product_version = RW_I93_ONS_N24RF64E;
+          break;
+        default:
+          p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+        break;
+      }
   } else {
     p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
   }
@@ -275,8 +303,8 @@
     rw_i93_get_product_version(p_uid);
 
     if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
-      if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
-        /* STM supports more than 2040 bytes */
+      if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) || (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS)){
+        /* STM & ONS supports more than 2040 bytes */
         p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
       }
     }
@@ -409,6 +437,36 @@
             }
           }
         }
+      } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS) {
+        /*
+        **  N36RW02:  00011010(b), blockSize: 4, numberBlocks: 0x40
+        **  N24RF04:  00101110(b), blockSize: 4, numberBlocks: 0x80
+        **  N24RF04E: 00101010(b), blockSize: 4, numberBlocks: 0x80
+        **  N24RF16:  01001010(b), blockSize: 4, numberBlocks: 0x200
+        **  N24RF16E: 01001110(b), blockSize: 4, numberBlocks: 0x200
+        **  N24RF64:  01101010(b), blockSize: 4, numberBlocks: 0x800
+        **  N24RF64E: 01101110(b), blockSize: 4, numberBlocks: 0x800
+        */
+          p_i93->block_size = 4;
+          switch (p_i93->product_version){
+            case RW_I93_ONS_N36RW02:
+                 p_i93->num_block = 0x40;
+                 break;
+            case RW_I93_ONS_N24RF04:
+            case RW_I93_ONS_N24RF04E:
+                 p_i93->num_block = 0x80;
+                 break;
+            case RW_I93_ONS_N24RF16:
+            case RW_I93_ONS_N24RF16E:
+                 p_i93->num_block = 0x200;
+                 break;
+            case RW_I93_ONS_N24RF64:
+            case RW_I93_ONS_N24RF64E:
+                 p_i93->num_block = 0x800;
+                 break;
+            default:
+                 return false;
+          }
       }
     }
   }
@@ -431,7 +489,7 @@
 
   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
 
-  if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
+  if (((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) || (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS)) &&
       (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
       (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
       (rw_i93_send_cmd_get_sys_info(nullptr, I93_FLAG_PROT_EXT_YES) ==
@@ -477,7 +535,7 @@
   if (flags & I93_FLAG_ERROR_DETECTED) {
     if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
       /* getting system info with protocol extension flag */
-      /* This STM tag supports more than 2040 bytes */
+      /* This STM & ONS tag supports more than 2040 bytes */
       p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
       p_i93->state = RW_I93_STATE_BUSY;
     } else if (length) {
@@ -1603,6 +1661,30 @@
       }
     }
 
+    if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS) {
+      /* N24RF04, N24RF04E, N24RF16, N24RF16E, N24RF64, N24RF64E requires
+      ** - The max number of blocks is 32 and they are all located in the
+      **   same sector.
+      ** - The sector is 32 blocks of 4 bytes.
+      */
+      if ((p_i93->product_version == RW_I93_ONS_N36RW02) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF04) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF04E)||
+          (p_i93->product_version == RW_I93_ONS_N24RF16) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF16E)||
+          (p_i93->product_version == RW_I93_ONS_N24RF64) ||
+          (p_i93->product_version == RW_I93_ONS_N24RF64E)) {
+        if (num_block > I93_ONS_MAX_BLOCKS_PER_READ)
+          num_block = I93_ONS_MAX_BLOCKS_PER_READ;
+
+        if ((first_block / I93_ONS_BLOCKS_PER_SECTOR) !=
+            ((first_block + num_block - 1) / I93_ONS_BLOCKS_PER_SECTOR)) {
+          num_block = I93_ONS_BLOCKS_PER_SECTOR -
+                      (first_block % I93_ONS_BLOCKS_PER_SECTOR);
+        }
+      }
+    }
+
     return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
   } else {
     return rw_i93_send_cmd_read_single_block(first_block, false);
@@ -1681,7 +1763,7 @@
   if (flags & I93_FLAG_ERROR_DETECTED) {
     if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
       /* getting system info with protocol extension flag */
-      /* This STM tag supports more than 2040 bytes */
+      /* This STM & ONS tag supports more than 2040 bytes */
       p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
     } else {
       DLOG_IF(INFO, nfc_debug_enabled)
@@ -1766,11 +1848,11 @@
       **         without any security)
       **       : Bit 1-0:Write access condition (00b: write access granted
       **         without any security)
-      ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
-      **         0xFF if more than 2040bytes]
-      ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
+      ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, ONS set
+      **         to 0xFF if more than 2040bytes]
+      ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM, ONS]
       **       : Bit 1:Inventory page read is supported [NXP]
-      **       : Bit 2:More than 2040 bytes are supported [STM]
+      **       : Bit 2:More than 2040 bytes are supported [STM, ONS]
       */
 
       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
@@ -2463,7 +2545,7 @@
       /* ignore error */
     } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
       /* getting system info with protocol extension flag */
-      /* This STM tag supports more than 2040 bytes */
+      /* This STM & ONS tag supports more than 2040 bytes */
       p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
       return;
     } else {
@@ -2709,7 +2791,7 @@
                   RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
         *(p++) = 0;
       } else {
-        /* STM except LRIS2K, Broadcom supports read multi block command */
+        /* STM except LRIS2K, ONS, Broadcom supports read multi block command */
 
         /* if memory size is more than 2040 bytes (which is not LRIS2K) */
         if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
@@ -4171,8 +4253,22 @@
       return "ST25DV04";
     case RW_I93_STM_ST25DVHIK:
       return "ST25DV";
+    case RW_I93_ONS_N36RW02:
+      return ("N36RW02");
+    case RW_I93_ONS_N24RF04:
+      return ("N24RF04");
+    case RW_I93_ONS_N24RF04E:
+      return ("N24RF04E");
+    case RW_I93_ONS_N24RF16:
+      return ("N24RF16");
+    case RW_I93_ONS_N24RF16E:
+      return ("N24RF16E");
+    case RW_I93_ONS_N24RF64:
+      return ("N24RF64");
+    case RW_I93_ONS_N24RF64E:
+      return ("N24RF64E");
     case RW_I93_UNKNOWN_PRODUCT:
     default:
       return "UNKNOWN";
   }
-}
+} 
\ No newline at end of file