2012-01-12 09:49:19 +01:00
|
|
|
#include <cutter.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "nfc/nfc.h"
|
2012-01-25 10:56:05 +01:00
|
|
|
#include "../utils/nfc-utils.h"
|
2012-01-12 09:49:19 +01:00
|
|
|
|
|
|
|
pthread_t threads[2];
|
|
|
|
nfc_connstring connstrings[2];
|
|
|
|
nfc_device *first_device, *second_device;
|
|
|
|
intptr_t result[2];
|
|
|
|
|
|
|
|
void
|
2012-05-29 17:54:36 +02:00
|
|
|
abort_test_by_keypress(int sig)
|
2012-01-12 09:49:19 +01:00
|
|
|
{
|
|
|
|
(void) sig;
|
2012-05-29 17:54:36 +02:00
|
|
|
printf("\033[0;1;31mSIGINT\033[0m");
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
nfc_abort_command(first_device);
|
|
|
|
nfc_abort_command(second_device);
|
2012-01-12 09:49:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_setup(void)
|
2012-01-12 09:49:19 +01:00
|
|
|
{
|
2012-05-29 17:54:36 +02:00
|
|
|
size_t n = nfc_list_devices(NULL, connstrings, 2);
|
2012-01-12 09:49:19 +01:00
|
|
|
if (n < 2) {
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_omit("At least two NFC devices must be plugged-in to run this test");
|
2012-01-12 09:49:19 +01:00
|
|
|
}
|
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
nfc_init(NULL);
|
|
|
|
second_device = nfc_open(NULL, connstrings[0]);
|
|
|
|
first_device = nfc_open(NULL, connstrings[1]);
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
signal(SIGINT, abort_test_by_keypress);
|
2012-01-12 09:49:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_teardown(void)
|
2012-01-12 09:49:19 +01:00
|
|
|
{
|
2012-05-29 17:54:36 +02:00
|
|
|
nfc_close(second_device);
|
|
|
|
nfc_close(first_device);
|
|
|
|
nfc_exit(NULL);
|
2012-01-12 09:49:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
struct thread_data {
|
|
|
|
nfc_device *device;
|
|
|
|
void *cut_test_context;
|
|
|
|
};
|
|
|
|
|
|
|
|
void *
|
2012-05-29 17:54:36 +02:00
|
|
|
target_thread(void *arg)
|
2012-01-12 09:49:19 +01:00
|
|
|
{
|
|
|
|
intptr_t thread_res = 0;
|
|
|
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_set_current_test_context(((struct thread_data *) arg)->cut_test_context);
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
printf("=========== TARGET %s =========\n", nfc_device_get_name(device));
|
2012-05-29 02:33:22 +02:00
|
|
|
nfc_target nt;
|
2012-01-13 15:41:27 +01:00
|
|
|
|
|
|
|
uint8_t abtRx[1024];
|
2012-05-29 17:54:36 +02:00
|
|
|
size_t szRx = sizeof(abtRx);
|
2012-01-13 15:41:27 +01:00
|
|
|
|
|
|
|
// 1) nfc_target_init should take target in idle mode
|
2012-05-29 17:54:36 +02:00
|
|
|
int res = nfc_target_init(device, &nt, abtRx, szRx, 500);
|
|
|
|
cut_assert_operator_int(res, >= , 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-01-13 15:41:27 +01:00
|
|
|
// 2) act as target
|
|
|
|
nfc_target nt1 = {
|
2012-01-12 09:49:19 +01:00
|
|
|
.nm = {
|
|
|
|
.nmt = NMT_DEP,
|
|
|
|
.nbr = NBR_UNDEFINED
|
|
|
|
},
|
|
|
|
.nti = {
|
|
|
|
.ndi = {
|
|
|
|
.abtNFCID3 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA },
|
|
|
|
.szGB = 4,
|
|
|
|
.abtGB = { 0x12, 0x34, 0x56, 0x78 },
|
|
|
|
.ndm = NDM_PASSIVE,
|
|
|
|
/* These bytes are not used by nfc_target_init: the chip will provide them automatically to the initiator */
|
|
|
|
.btDID = 0x00,
|
|
|
|
.btBS = 0x00,
|
|
|
|
.btBR = 0x00,
|
|
|
|
.btTO = 0x00,
|
|
|
|
.btPP = 0x01,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
2012-01-13 15:41:27 +01:00
|
|
|
sleep(6);
|
2012-05-29 17:54:36 +02:00
|
|
|
res = nfc_target_init(device, &nt1, abtRx, szRx, 0);
|
|
|
|
cut_assert_operator_int(res, > , 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
|
|
|
|
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
2012-01-12 09:49:19 +01:00
|
|
|
szRx = (size_t) res;
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-01-12 09:49:19 +01:00
|
|
|
const uint8_t abtAttRx[] = "Hello DEP target!";
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, szRx, cut_message("Invalid received data"));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-01-12 09:49:19 +01:00
|
|
|
const uint8_t abtTx[] = "Hello DEP initiator!";
|
2012-05-29 17:54:36 +02:00
|
|
|
res = nfc_target_send_bytes(device, abtTx, sizeof(abtTx), 500);
|
|
|
|
cut_assert_operator_int(res, > , 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
2012-01-13 10:58:47 +01:00
|
|
|
|
|
|
|
// 3) idle mode
|
2012-05-29 17:54:36 +02:00
|
|
|
sleep(1);
|
|
|
|
nfc_idle(device);
|
2012-01-12 09:49:19 +01:00
|
|
|
|
|
|
|
return (void *) thread_res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
2012-05-29 17:54:36 +02:00
|
|
|
initiator_thread(void *arg)
|
2012-01-12 09:49:19 +01:00
|
|
|
{
|
|
|
|
intptr_t thread_res = 0;
|
|
|
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_set_current_test_context(((struct thread_data *) arg)->cut_test_context);
|
2012-01-12 09:49:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Wait some time for the other thread to initialise NFC device as target
|
|
|
|
*/
|
2012-05-29 17:54:36 +02:00
|
|
|
sleep(5);
|
|
|
|
printf("=========== INITIATOR %s =========\n", nfc_device_get_name(device));
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
int res = nfc_initiator_init(device);
|
|
|
|
cut_assert_equal_int(0, res, cut_message("Can't initialize NFC device as initiator: %s", nfc_strerror(device)));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 02:33:22 +02:00
|
|
|
// 1) As other device should be in idle mode, nfc_initiator_poll_dep_target should return 0
|
2012-01-12 09:49:19 +01:00
|
|
|
nfc_target nt;
|
2012-05-29 17:54:36 +02:00
|
|
|
res = nfc_initiator_poll_dep_target(device, NDM_PASSIVE, NBR_106, NULL, &nt, 1000);
|
|
|
|
cut_assert_equal_int(0, res, cut_message("Problem with nfc_idle"));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res != 0) { thread_res = -1; return (void *) thread_res; }
|
2012-01-13 10:58:47 +01:00
|
|
|
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-01-13 10:58:47 +01:00
|
|
|
// 2 As other device should be in target mode, nfc_initiator_poll_dep_target should be positive.
|
|
|
|
nfc_target nt1;
|
2012-01-12 09:49:19 +01:00
|
|
|
|
|
|
|
// Passive mode / 106Kbps
|
2012-05-29 17:54:36 +02:00
|
|
|
printf("=========== INITIATOR %s (Passive mode / 106Kbps) =========\n", nfc_device_get_name(device));
|
|
|
|
res = nfc_initiator_poll_dep_target(device, NDM_PASSIVE, NBR_106, NULL, &nt1, 5000);
|
|
|
|
cut_assert_operator_int(res, > , 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
|
|
|
cut_assert_equal_int(NMT_DEP, nt1.nm.nmt, cut_message("Invalid target modulation"));
|
|
|
|
cut_assert_equal_int(NBR_106, nt1.nm.nbr, cut_message("Invalid target baud rate"));
|
|
|
|
cut_assert_equal_memory("\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA", 10, nt1.nti.ndi.abtNFCID3, 10, cut_message("Invalid target NFCID3"));
|
|
|
|
cut_assert_equal_int(NDM_PASSIVE, nt1.nti.ndi.ndm, cut_message("Invalid target DEP mode"));
|
|
|
|
cut_assert_equal_memory("\x12\x34\x56\x78", 4, nt1.nti.ndi.abtGB, nt1.nti.ndi.szGB, cut_message("Invalid target general bytes"));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
2012-01-12 09:49:19 +01:00
|
|
|
|
|
|
|
const uint8_t abtTx[] = "Hello DEP target!";
|
|
|
|
uint8_t abtRx[1024];
|
2012-05-29 17:54:36 +02:00
|
|
|
size_t szRx = sizeof(abtRx);
|
|
|
|
res = nfc_initiator_transceive_bytes(device, abtTx, sizeof(abtTx), abtRx, &szRx, 500);
|
|
|
|
cut_assert_operator_int(res, >= , 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
2012-01-12 09:49:19 +01:00
|
|
|
|
|
|
|
const uint8_t abtAttRx[] = "Hello DEP initiator!";
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, szRx, cut_message("Invalid received data"));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
res = nfc_initiator_deselect_target(device);
|
|
|
|
cut_assert_operator_int(res, >= , 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
2012-01-13 10:58:47 +01:00
|
|
|
|
2012-05-29 02:33:22 +02:00
|
|
|
// 3) As other device should be in idle mode, nfc_initiator_poll_dep_target should return 0
|
2012-01-13 10:58:47 +01:00
|
|
|
nfc_target nt2;
|
2012-05-29 17:54:36 +02:00
|
|
|
res = nfc_initiator_poll_dep_target(device, NDM_PASSIVE, NBR_106, NULL, &nt2, 1000);
|
|
|
|
cut_assert_equal_int(0, res, cut_message("Problem with nfc_idle"));
|
2012-05-29 17:55:35 +02:00
|
|
|
if (res != 0) { thread_res = -1; return (void *) thread_res; }
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-01-12 09:49:19 +01:00
|
|
|
return (void *) thread_res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-29 17:54:36 +02:00
|
|
|
test_dep_states(void)
|
2012-01-12 09:49:19 +01:00
|
|
|
{
|
|
|
|
int res;
|
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
CutTestContext *test_context = cut_get_current_test_context();
|
2012-01-12 09:49:19 +01:00
|
|
|
struct thread_data target_data = {
|
|
|
|
.device = first_device,
|
|
|
|
.cut_test_context = test_context,
|
|
|
|
};
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-05-29 17:52:51 +02:00
|
|
|
struct thread_data initiator_data = {
|
2012-01-12 09:49:19 +01:00
|
|
|
.device = second_device,
|
|
|
|
.cut_test_context = test_context,
|
|
|
|
};
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-01-12 09:49:19 +01:00
|
|
|
for (int i = 0; i < 2; i++) {
|
2012-05-29 17:54:36 +02:00
|
|
|
if ((res = pthread_create(&(threads[1]), NULL, target_thread, &target_data)))
|
|
|
|
cut_fail("pthread_create() returned %d", res);
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
if ((res = pthread_create(&(threads[0]), NULL, initiator_thread, &initiator_data)))
|
|
|
|
cut_fail("pthread_create() returned %d", res);
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
if ((res = pthread_join(threads[0], (void *) &result[0])))
|
|
|
|
cut_fail("pthread_join() returned %d", res);
|
|
|
|
if ((res = pthread_join(threads[1], (void *) &result[1])))
|
|
|
|
cut_fail("pthread_join() returned %d", res);
|
2012-01-12 09:49:19 +01:00
|
|
|
|
2012-05-29 17:54:36 +02:00
|
|
|
cut_assert_equal_int(0, result[0], cut_message("Unexpected initiator return code"));
|
|
|
|
cut_assert_equal_int(0, result[1], cut_message("Unexpected target return code"));
|
2012-05-29 02:33:22 +02:00
|
|
|
|
2012-01-13 10:58:47 +01:00
|
|
|
// initiator --> target, target --> initiator
|
2012-01-12 09:49:19 +01:00
|
|
|
target_data.device = second_device;
|
|
|
|
initiator_data.device = first_device;
|
|
|
|
}
|
|
|
|
}
|