Created
June 2, 2016 08:49
-
-
Save Komarev/7c35c977ffe0fec6f49acde760a1a0cd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@WorkerThread | |
public static void writePage(NfcA nfca, byte offset, byte[] page) | |
throws NfcWritePageException { | |
byte[] cmd = new byte[] {COMMAND_WRITE_RECORD, offset, 0, 0, 0, 0}; | |
try { | |
System.arraycopy(page, 0, cmd, 2, 4); | |
nfca.transceive(cmd); | |
} catch (Exception e) { | |
throw new NfcWritePageException( | |
"Write page error. Offset " + StringUtils.byteToHex(offset)); | |
} | |
} | |
@WorkerThread | |
public static byte[] readPage(NfcA nfca, byte offset) throws NfcReadPageException { | |
byte[] result; | |
try { | |
result = nfca.transceive(new byte[] {COMMAND_READ_RECORD, offset}); | |
} catch (Exception e) { | |
throw new NfcReadPageException( | |
"Read page error. Offset " + StringUtils.byteToHex(offset) + e.getMessage()); | |
} | |
return result; | |
} | |
@WorkerThread | |
public static void prepareToIO(NfcA nfca) throws NfcOperationException { | |
byte[] buffer; | |
selectSector(nfca, SECTOR_3); | |
buffer = readPage(nfca, SECTOR_3_SESSION_REGISTER_PAGE_1_OFFSET); | |
if ((buffer[NC_REG_BYTE_NUMBER] & MASK_PTHRU_ON_OFF) != MASK_PTHRU_ON_OFF) { | |
throw new NfcControllerNotReady("Prepare IO: Controller not ready"); | |
} | |
long startTime = System.currentTimeMillis() + READ_TIMEOUT_MS; | |
while (true) { | |
if (startTime < System.currentTimeMillis()) { | |
throw new NfcTimeoutException("Prepare IO: Timeout"); | |
} | |
try { | |
buffer = readPage(nfca, SECTOR_3_SESSION_REGISTER_PAGE_1_OFFSET); | |
} catch (Exception e) { | |
continue; | |
} | |
if ((buffer[NC_REG_BYTE_NUMBER] & MASK_CONTROLLER_READY_TO_READ) | |
== MASK_CONTROLLER_READY_TO_READ) { | |
break; | |
} | |
} | |
} | |
@WorkerThread | |
public static void checkForOperationSuccess(NfcA nfca) throws NfcOperationException { | |
byte[] buffer; | |
long tryCounter = 0; | |
long failedFlagCounter = 0; | |
selectSector(nfca, SECTOR_3); | |
long startTime = System.currentTimeMillis() + READ_TIMEOUT_MS; | |
while (true) { | |
tryCounter++; | |
if (startTime < System.currentTimeMillis()) { | |
throw new NfcTimeoutException( | |
"Check for success timeout. Tries=" + Long.toString(tryCounter) | |
+ " failedFlagCount=" + Long.toString(failedFlagCounter)); | |
} | |
buffer = readPage(nfca, SECTOR_3_SESSION_REGISTER_PAGE_2_OFFSET); | |
failedFlagCounter++; | |
if ((buffer[NS_REG_BYTE_NUMBER] & MASK_SRAM_RF_READY) == MASK_SRAM_RF_READY) { | |
break; | |
} | |
} | |
} | |
@WorkerThread | |
public static void writeOperationCommand(NfcA nfca, String command) | |
throws NfcOperationException { | |
selectSector(nfca, SECTOR_1); | |
try { | |
byte[] buffer = command.getBytes(ASCII); | |
int fullpagesCount = buffer.length / 4; | |
int charsInLastPage = buffer.length - fullpagesCount * 4; | |
for (int i = 0; i < fullpagesCount; i++) { | |
writePage(nfca, (byte) (SRAM_FIRST_PAGE_OFFSET + i), | |
Arrays.copyOfRange(buffer, i * 4, i * 4 + 4)); | |
} | |
if (charsInLastPage > 0) { | |
writePage(nfca, (byte) (SRAM_FIRST_PAGE_OFFSET + fullpagesCount), | |
String.format(FORMAT_PAGE_STRING, command.substring(fullpagesCount * 4)) | |
.getBytes(ASCII)); | |
} | |
writePage(nfca, SRAM_LAST_PAGE_OFFSET, new byte[] {0x30, 0x30, 0x30, 0x30}); | |
} catch (UnsupportedEncodingException e) { | |
throw new NfcWriteOperationException("Write operation exception"); | |
} | |
} | |
@WorkerThread | |
public static String readOperationAnswer(NfcA nfca) throws NfcOperationException { | |
byte[] buffer; | |
selectSector(nfca, SECTOR_1); | |
List<Byte> sram = new ArrayList<>(); | |
for (byte i = SRAM_FIRST_PAGE_OFFSET; i <= SRAM_LAST_PAGE_OFFSET; i++) { | |
buffer = readPage(nfca, i); | |
sram.add(buffer[0]); | |
sram.add(buffer[1]); | |
sram.add(buffer[2]); | |
sram.add(buffer[3]); | |
if (buffer[0] == END || buffer[1] == END || buffer[2] == END || buffer[3] == END) { | |
break; | |
} | |
} | |
byte[] result = new byte[sram.size()]; | |
for (int i = 0; i < result.length; i++) { | |
result[i] = sram.get(i); | |
} | |
String resultMessage; | |
try { | |
resultMessage = new String(result, ASCII); | |
} catch (UnsupportedEncodingException e) { | |
resultMessage = "Unsupported encoding " + ASCII; | |
} | |
return resultMessage; | |
} | |
public static Observable<String> resetClock(NfcA nfca, long timestamp) { | |
return Observable.fromCallable(() -> { | |
prepareToIO(nfca); | |
writeOperationCommand(nfca, | |
NfcOperationFactory.getCommandForTimeSetup(timestamp)); | |
checkForOperationSuccess(nfca); | |
return readOperationAnswer(nfca); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment