+ char cmdp = param_getchar(Cmd, 0);
+ uint8_t blockno = -1;
+ uint8_t data[4] = {0x00};
+ bool isSrix4k = true;
+ char str[20];
+
+ if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
+ PrintAndLog(" [1 = SRIX4K]");
+ PrintAndLog(" [2 = SRI512]");
+ PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
+ PrintAndLog(" sample: hf 14b write 1 7F 11223344");
+ PrintAndLog(" : hf 14b write 1 FF 11223344");
+ PrintAndLog(" : hf 14b write 2 15 11223344");
+ PrintAndLog(" : hf 14b write 2 FF 11223344");
+ return 0;
+ }
+
+ if ( cmdp == '2' )
+ isSrix4k = false;
+
+ //blockno = param_get8(Cmd, 1);
+
+ if ( param_gethex(Cmd,1, &blockno, 2) ) {
+ PrintAndLog("Block number must include 2 HEX symbols");
+ return 0;
+ }
+
+ if ( isSrix4k ){
+ if ( blockno > 0x7f && blockno != 0xff ){
+ PrintAndLog("Block number out of range");
+ return 0;
+ }
+ } else {
+ if ( blockno > 0x0f && blockno != 0xff ){
+ PrintAndLog("Block number out of range");
+ return 0;
+ }
+ }
+
+ if (param_gethex(Cmd, 2, data, 8)) {
+ PrintAndLog("Data must include 8 HEX symbols");
+ return 0;
+ }
+
+ if ( blockno == 0xff)
+ PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
+ else
+ PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
+
+ sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
+
+ CmdHF14BCmdRaw(str);
+ return 0;
+}
+
+int srix4kChecksum(uint32_t value) {
+/*
+// vv = value
+// pp = position
+// vv vv vv pp
+4 bytes : 00 1A 20 01
+*/
+
+#define NibbleHigh(b) ( (b & 0xF0) >> 4 )
+#define NibbleLow(b) ( b & 0x0F )
+#define Crumb(b,p) (((b & (0x3 << p) ) >> p ) & 0xF)
+
+ // only the lower crumbs.
+ uint8_t block = (value & 0xFF);
+ uint8_t i = 0;
+ uint8_t valuebytes[] = {0,0,0};
+
+ // if ( strlen(Cmd) > 0){
+ // value = param_get32ex(Cmd, 0, 0, 16);
+
+ // block = value & 0xFF;
+
+ // value &= 0xFFFFFF00;
+ // value >>=8;
+ // }
+
+ num_to_bytes(value, 3, valuebytes);
+
+ // Scrambled part
+ // Crumb swapping of value.
+ uint8_t temp[] = {0,0};
+ temp[0] = (Crumb(value, 22) << 4 | Crumb(value, 14 ) << 2 | Crumb(value, 6)) << 4;
+ temp[0] |= Crumb(value, 20) << 4 | Crumb(value, 12 ) << 2 | Crumb(value, 4);
+ temp[1] = (Crumb(value, 18) << 4 | Crumb(value, 10 ) << 2 | Crumb(value, 2)) << 4;
+ temp[1] |= Crumb(value, 16) << 4 | Crumb(value, 8 ) << 2 | Crumb(value, 0);
+
+ // chksum part
+ uint32_t chksum = 0xFF - block;
+
+ // chksum is reduced by each nibbles of value.
+ for (i = 0; i < 3; ++i){
+ chksum -= NibbleHigh(valuebytes[i]);
+ chksum -= NibbleLow(valuebytes[i]);
+ }
+
+ // base4 conversion
+ // and left shift twice
+ i = 3;
+ uint8_t base4[] = {0,0,0,0};
+ while( chksum !=0 ){
+ base4[i--] = (chksum % 4 << 2);
+ chksum /= 4;
+ }
+
+ // merge scambled and chksum parts
+ uint32_t encvalue =
+ ( NibbleLow ( base4[0]) << 28 ) |
+ ( NibbleHigh( temp[0]) << 24 ) |
+
+ ( NibbleLow ( base4[1]) << 20 ) |
+ ( NibbleLow ( temp[0]) << 16 ) |
+
+ ( NibbleLow ( base4[2]) << 12 ) |
+ ( NibbleHigh( temp[1]) << 8 ) |
+
+ ( NibbleLow ( base4[3]) << 4 ) |
+ NibbleLow ( temp[1] );
+
+ PrintAndLog("ICE | %08X", encvalue);
+ return 0;
+}
+int srix4kMagicbytes(){
+ return 0;
+}
+int srix4kValid(){
+ return 0;