ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
ruuvi_interface_communication_nfc_test.c
Go to the documentation of this file.
2 #if RUUVI_RUN_TESTS
3 #include "ruuvi_driver_error.h"
4 #include "ruuvi_driver_test.h"
9 #include "ruuvi_interface_rtc.h"
10 #include <stdbool.h>
11 #include <string.h>
12 #include <stdio.h>
13 
26 #define NFC_TEST_TIMEOUT_MS (20000U)
27 
28 static ri_comm_channel_t m_channel;
29 static bool m_has_connected;
30 static bool m_has_disconnected;
31 static bool m_has_sent;
32 static bool m_has_received;
33 static ri_comm_message_t rx_data;
34 
35 static rd_status_t nfc_isr (ri_comm_evt_t evt,
36  void * p_data, size_t data_len)
37 {
38  switch (evt)
39  {
40  // Note: This gets called only after the NFC notifications have been registered.
41  case RI_COMM_CONNECTED:
42  m_has_connected = true;
43  break;
44 
46  m_has_disconnected = true;
47  break;
48 
49  case RI_COMM_SENT:
50  m_has_sent = true;
51  break;
52 
53  case RI_COMM_RECEIVED:
54  m_has_received = true;
56  m_channel.read (&rx_data);
57  break;
58 
59  default:
60  break;
61  }
62 
63  return RD_SUCCESS;
64 }
65 
66 /*
67  * Initializes NFC hardware.
68  *
69  * @retval RD_SUCCESS on success,
70  * @retval RD_ERROR_INVALID_STATE if NFC is already initialized
71  */
72 static bool ri_nfc_init_test (const rd_test_print_fp printfp)
73 {
74  bool status = false;
75  rd_status_t err_code = RD_SUCCESS;
76  printfp ("\"init\":");
77  err_code |= ri_nfc_init (&m_channel);
78 
79  if (RD_SUCCESS == err_code)
80  {
81  err_code |= ri_nfc_init (&m_channel);
82 
83  if (RD_ERROR_INVALID_STATE == err_code)
84  {
85  err_code = ri_nfc_uninit (&m_channel);
86  err_code = ri_nfc_init (&m_channel);
87 
88  if (RD_SUCCESS != err_code)
89  {
90  status = true;
91  }
92  }
93  else
94  {
95  status = true;
96  }
97  }
98  else
99  {
100  status = true;
101  }
102 
103  if (status)
104  {
105  printfp ("\"fail\",\r\n");
106  }
107  else
108  {
109  printfp ("\"pass\",\r\n");
110  }
111 
112  ri_nfc_uninit (&m_channel);
113  return status;
114 }
115 
122 bool ri_nfc_rx_test (const rd_test_print_fp printfp)
123 {
124  bool status = false;
125  uint64_t start_time = 0;
126  bool timeout = false;
127  rd_status_t err_code = RD_SUCCESS;
128  printfp ("\"tx_rx\":");
129  err_code |= ri_nfc_init (&m_channel);
130  const char test_data[] = "Lorem Ipsum";
131  ri_comm_message_t msg = {0};
132  snprintf ( (char *) & msg.data, RI_COMM_MESSAGE_MAX_LENGTH, "%s", test_data);
133  msg.data_length = strlen (test_data);
134 
135  if (RD_SUCCESS == err_code)
136  {
137  m_channel.on_evt = nfc_isr;
138  err_code |= m_channel.send (&msg);
139  ri_rtc_init();
140  start_time = ri_rtc_millis();
141 
142  while (! (m_has_connected
143  && m_has_disconnected
144  && m_has_sent
145  && m_has_received))
146  {
147  if ( (start_time + NFC_TEST_TIMEOUT_MS) < ri_rtc_millis())
148  {
149  timeout = true;
150  break;
151  }
152  }
153 
154  if (false == timeout)
155  {
156  if ( (RD_SUCCESS != err_code)
157  || memcmp (&rx_data, &msg, sizeof (ri_comm_message_t)))
158  {
159  status = true;
160  }
161  }
162  }
163  else
164  {
165  status = true;
166  }
167 
168  if (timeout)
169  {
170  printfp ("\"timeout\"\r\n");
171  }
172  else
173  {
174  if (status)
175  {
176  printfp ("\"fail\"\r\n");
177  }
178  else
179  {
180  printfp ("\"pass\"\r\n");
181  }
182  }
183 
184  ri_rtc_uninit();
185  ri_nfc_uninit (&m_channel);
186  return status;
187 }
188 
190 {
191  rd_status_t status = false;
192  printfp ("\"nfc\":{\r\n");
193  status |= ri_nfc_init_test (printfp);
194  status |= ri_nfc_rx_test (printfp);
195  printfp ("}\r\n");
196  return status;
197 }
198 #endif
uint32_t rd_status_t
bitfield for representing errors
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
bool ri_communication_nfc_run_integration_test(const rd_test_print_fp printfp)
void(* rd_test_print_fp)(const char *const msg)
function pointer to print test information
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Functions for testing drivers.
#define RI_COMM_MESSAGE_MAX_LENGTH
The maximum length for the application message for sending over BLE, which depends on whether extende...
ri_comm_evt_t
Communication event type.
@ RI_COMM_CONNECTED
Connection established, OK to send, may receive data.
@ RI_COMM_RECEIVED
New data received, available to read with read function.
@ RI_COMM_SENT
One queued message was sent with all repetitions.
@ RI_COMM_DISCONNECTED
Connection lost, cannot send, may not receive data.
rd_status_t ri_nfc_init(ri_comm_channel_t *const channel)
rd_status_t ri_nfc_uninit(ri_comm_channel_t *const channel)
rd_status_t ri_rtc_init(void)
Initializes RTC at 0 ms.
rd_status_t ri_rtc_uninit(void)
Stop RTC if applicable.
uint64_t ri_rtc_millis(void)
Get milliseconds since init.
control API for communication via outside world
ri_comm_evt_handler_fp_t on_evt
Callback to application-level event handler, must be set in application.
ri_comm_xfer_fp_t send
Asynchronous send function.
ri_comm_xfer_fp_t read
Asynchronous read function.
Application message structure used for communication.
uint8_t data[RI_COMM_MESSAGE_MAX_LENGTH]
Data payload.
uint8_t data_length
Length of data.