android - studio - Arduino: uint8_t array a cadena
nfc android studio (2)
Tengo una aplicación NFC creada en Android que envía un hash como respuesta de apdu. Este es el código que uso en mi aplicación de Android para enviar el hash:
@Override
public byte[] processCommandApdu(byte[] arg0, Bundle arg1) {
String hash = "e68d3f574009cbbe011150263634c5c0";
return hash.getBytes(Charset.forName("UTF-8"));
}
Ahora cuando lo recibo del lado de Arduino obtengo estos datos SIN PROCESAR:
10154561005110253555248485799989810148494949534850255255255255255255255255255
¿Cómo recupero el hash de eso?
Esto es lo que tengo ahora, pero obviamente no funciona:
uint8_t response[32];
uint8_t responseLength = sizeof(response);
if (nfc.inDataExchange(message, sizeof(message), response, &responseLength)) {
Serial.print("RAW: ");
for (int i = 0; i < sizeof(response); i++) {
Serial.print(response[i]);
}
Serial.println(" ");
char buffer[32];
itoa((int)response,buffer,8);
Serial.print("ITOA: ");
for (int i = 0; i < sizeof(buffer); i++) {
Serial.print(buffer[i]);
}
Serial.println(" ");
}
Y esta es la salida serial del código de arriba:
RAW: 10154561005110253555248485799989810148494949534850255255255255255255255255255
ITOA: 4253 µ +
3ü R
¡Halp!
OK, así que descubrí mi respuesta. No necesito itoa. Puedo encasillar la entrada RAW en char y obtener lo que necesito:
Serial.print("TYPECASTED RAW: ");
for (int i = 0; i < sizeof(response); i++) {
Serial.print((char)response[i]);
}
Serial.println(" ");
Y eso superado:
e68d3f574009cbbe0111502ÿÿÿÿÿÿÿÿÿ
Ahora me pregunto por qué los últimos 9 caracteres están siendo reemplazados por 255.
Tres sugerencias, aunque ninguna de ellas explica por qué se truncan los últimos bytes:
No convierta la representación de hash hexadecimal en una cadena de caracteres para luego enviar esos caracteres en codificación UTF-8. Sería mucho más eficiente (y menos esfuerzo de descodificación) enviar directamente el hash como bytes:
@Override public byte[] processCommandApdu(byte[] arg0, Bundle arg1) { byte[] hash = { (byte)0xe6, (byte)0x8d, (byte)0x3f, (byte)0x57, (byte)0x40, (byte)0x09, (byte)0xcb, (byte)0xbe, (byte)0x01, (byte)0x11, (byte)0x50, (byte)0x26, (byte)0x36, (byte)0x34, (byte)0xc5, (byte)0xc0 }; return hash; }
Si ya tiene el hash como una cadena hexadecimal, le sugiero que primero lo convierta a su representación de bytes en el lado de Android.
Cuando utilice HCE, debe adherirse a las APDU ISO / IEC 7816-4 en lugar de simplemente enviar datos aleatorios. Una APDU de comando (formato corto) consta de lo siguiente:
+----------+----------+----------+----------+----------+------------+----------+ | CLA | INS | P1 | P2 | Lc | DATA | Le | | (1 Byte) | (1 Byte) | (1 Byte) | (1 Byte) | (1 Byte) | (Lc Bytes) | (1 Byte) | +----------+----------+----------+----------+----------+------------+----------+
Donde Lc codifica la cantidad de bytes de DATA. Si DATA está vacío, Lc también está vacío. Le codifica la cantidad de bytes esperados como respuesta (con el caso especial de Le = 0x00, lo que significa 256 bytes de respuesta esperados.
Una APDU de respuesta ( eso es lo que envía como valor de retorno en
processCommandApdu
) se ve así:+----------+----------+----------+ | DATA | SW1 | SW2 | | (n Byte) | (1 Byte) | (1 Byte) | +----------+----------+----------+
DATA es la información de respuesta. SW1 y SW2 forman la palabra de estado de respuesta (típicamente SW1 = 0x90, SW2 = 0x00 para tener éxito). Tenga en cuenta que SW1 y SW2 son obligatorios.
Al iterar a través de la respuesta de
inDataExchange
utilice la longitud de respuesta proporcionada por esa función (responseLength
) en lugar de la longitud máxima de la memoria intermedia:for (int i = 0; i < responseLength; ++i) { ... }
Además, sugiero que proporcione un búfer con una longitud de respuesta superior a la máxima esperada. (Particularmente en su caso donde usa la codificación UTF-8 para una cadena de 32 caracteres, lo que podría (para algunos caracteres) dar como resultado más de 32 bytes).