Martyn Gilbertson / M24SR
Revision:
2:de5aea7f83cd
Parent:
1:e356ce0033e4
Child:
3:5ebf4b2c51a1
--- a/M24SR.cpp	Fri Jul 19 16:08:18 2019 +0100
+++ b/M24SR.cpp	Wed Jul 31 09:33:56 2019 +0100
@@ -95,10 +95,11 @@
 #define M24SR_DEFAULT_FREQUENCY (uint32_t)500000
 
 
-M24SR::M24SR(PinName sda, PinName scl, uint8_t address) : _i2c(sda,scl), _addr(address),
+M24SR::M24SR(PinName sda, PinName scl, uint8_t address, uint8_t *pass) : _i2c(sda,scl), _addr(address),
 		_session_open(false), _ndef_size(0), _ndef_hdr_size(0), _write_bytes(0)
 {
 	frequency(M24SR_DEFAULT_FREQUENCY);
+	password(pass);
 }
 
 
@@ -108,12 +109,130 @@
 }
 
 
+void M24SR::password(uint8_t *pass)
+{
+	memcpy(_password, pass, 16);
+}
+
+
 void M24SR::frequency(uint32_t hz)
 {
 	_i2c.frequency(hz);
 }
 
 
+M24SR::status_t M24SR::verify(bool with_password)
+{
+	status_t ret;
+    uint16_t length;
+
+	// verify with password
+    if (with_password)
+    {
+		C_APDU command(C_APDU_CLA_DEFAULT, C_APDU_VERIFY, 0x0003, 16, _password, 0);
+
+		/* build the I2C command */
+		build_I_block_command(CMD_MASK_VERIFY_BINARY_WITH_PWD, &command, 0x00, &length, _packet_data);
+
+    }else{
+    	// verify with no password
+
+		C_APDU command(C_APDU_CLA_DEFAULT, C_APDU_VERIFY, 0x0003, 0, NULL, 0);
+
+		/* build the I2C command */
+		build_I_block_command(CMD_MASK_VERIFY_BINARY_WO_PWD, &command, 0x00, &length, _packet_data);
+    }
+
+    if ( _i2c.write(M24SR_DEFAULT_ADDRESS, (const char*) _packet_data, length) != 0 )
+    {
+    	return M24SR_IO_ERROR_I2CTIMEOUT;
+    }
+
+    ret = io_poll_i2c();
+    if (ret == M24SR_SUCCESS)
+    {
+        if ( _i2c.read(M24SR_DEFAULT_ADDRESS, (char*) _packet_data, STATUS_RESPONSE_LENGTH ) != 0 )
+        {
+            ret = M24SR_IO_ERROR_I2CTIMEOUT;
+        }else{
+        	ret = is_correct_crc_residue(_packet_data, STATUS_RESPONSE_LENGTH);
+        }
+    }
+
+    return ret;
+}
+
+
+M24SR::status_t M24SR::set_system_gpo(nfc_gpo_state_t rf, nfc_gpo_state_t i2c)
+{
+	status_t ret;
+	uint8_t gpo_state;
+	uint8_t new_state = (rf << 4) | i2c;
+
+	if (  (ret = get_session(1)) != M24SR_SUCCESS )
+	{
+		// printf("Error opening session %4.4X\n", ret);
+		return ret;
+	}
+
+	if ( (ret = select_type((uint8_t*)SELECT_APPLICATION_COMMAND, 7, 0x0400, CMD_MASK_SELECT_APPLICATION)) != M24SR_SUCCESS)
+	{
+		// printf("Error Select Application %4.4X\n", ret );
+		return ret;
+	}
+
+	if ( (ret = select_type((uint8_t*)SYSTEM_FILE_ID_BYTES, 2, 0x000C, CMD_MASK_SELECT_CC_FILE)) != M24SR_SUCCESS)
+	{
+		// printf("Error select System file\r\n");
+		return ret;
+	}
+
+
+	// get GPO state
+	if ( (ret = read_binary( 0x0004, 1, (uint8_t*)&gpo_state )) != M24SR_SUCCESS )
+	{
+		//printf("Error read System File %4.4X\n", ret );
+		return ret;
+	}
+
+	//printf("New State: %2.2X Old State: %2.2X\n", new_state, gpo_state);
+
+	if (gpo_state == new_state)
+	{
+		return M24SR_SUCCESS;
+	}
+
+	verify(_password);
+
+	// write new GPO state
+	if ( (ret = update_binary( 0x0004, 1, (uint8_t*)&new_state )) != M24SR_SUCCESS )
+	{
+		//printf("Error update System File %4.4X\n", ret );
+		return ret;
+	}
+
+	// verify GPO state
+	if ( (ret = read_binary( 0x0004, 1, (uint8_t*)&gpo_state )) != M24SR_SUCCESS )
+	{
+		//printf("Error read System File %4.4X\n", ret );
+		return ret;
+	}
+
+	if (gpo_state != new_state)
+	{
+		//printf("Error updating GPO State\r\n");
+		return M24SR_UNSUCESSFUL_UPDATING;
+	}
+
+
+	deselect();
+	//printf("Updated GPO State:%2.2X", gpo_state);
+
+	return ret;
+}
+
+
+
 M24SR::status_t M24SR::session_start(bool parse_header)
 {
 	status_t ret;
@@ -798,6 +917,7 @@
     return (*lpw_crc);
 }
 
+
 M24SR::status_t M24SR::io_poll_i2c()
 {
     /* Make sure we don't block forever */
@@ -812,3 +932,5 @@
 
     return (status == 0) ? M24SR_SUCCESS : M24SR_IO_ERROR_I2CTIMEOUT;
 }
+
+