ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
ruuvi_task_nfc.c
Go to the documentation of this file.
1 
20 #if RT_NFC_ENABLED
21 #include "ruuvi_driver_error.h"
22 #include "ruuvi_interface_atomic.h"
27 #include "ruuvi_task_nfc.h"
28 #include <stdio.h>
29 #include <string.h>
30 
31 static ri_comm_channel_t m_channel;
32 static ri_comm_cb_t m_on_connected;
33 static ri_comm_cb_t m_on_disconnected;
34 static ri_comm_cb_t m_on_received;
35 static ri_comm_cb_t m_on_sent;
36 static bool m_nfc_is_connected;
37 static bool m_nfc_is_initialized;
38 
57 #ifndef CEEDLING
58 static
59 #endif
60 rd_status_t rt_nfc_isr (ri_comm_evt_t evt, void * p_data, size_t data_len)
61 {
62  switch (evt)
63  {
64  // Note: This gets called only after the NFC notifications have been registered.
65  case RI_COMM_CONNECTED:
66  m_nfc_is_connected = true;
67  (NULL != m_on_connected) ? m_on_connected (p_data, data_len) : false;
68  break;
69 
71  m_nfc_is_connected = false;
72  (NULL != m_on_disconnected) ? m_on_disconnected (p_data, data_len) : false;
73  break;
74 
75  case RI_COMM_SENT:
76  (NULL != m_on_sent) ? m_on_sent (p_data, data_len) : false;
77  break;
78 
79  case RI_COMM_RECEIVED:
80  (NULL != m_on_received) ? m_on_received (p_data, data_len) : false;
81  break;
82 
83  default:
84  break;
85  }
86 
87  return RD_SUCCESS;
88 }
89 
90 #ifndef CEEDLING
91 static
92 #endif
93 rd_status_t sw_set (const char * const sw)
94 {
95  rd_status_t err_code = RD_SUCCESS;
96  int written = 0;
97 
98  if (NULL == sw)
99  {
100  err_code |= RD_ERROR_NULL;
101  }
102  else
103  {
104  uint8_t fw_string[RI_COMM_DIS_STRLEN] = { 0 };
105  written = snprintf ( (char *) fw_string,
107  "SW: %s",
108  sw);
109 
110  if ( (0 > written)
111  || (RI_COMM_DIS_STRLEN <= written))
112  {
113  err_code |= RD_ERROR_INVALID_LENGTH;
114  }
115  else
116  {
117  err_code |= ri_nfc_fw_version_set (fw_string,
118  strlen ( (char *) fw_string));
119  }
120  }
121 
122  return err_code;
123 }
124 
125 #ifndef CEEDLING
126 static
127 #endif
128 rd_status_t mac_set (const char * const mac)
129 {
130  rd_status_t err_code = RD_SUCCESS;
131  int written = 0;
132 
133  if (NULL == mac)
134  {
135  err_code |= RD_ERROR_NULL;
136  }
137  else
138  {
139  uint8_t name[RI_COMM_DIS_STRLEN] = { 0 };
140  written = snprintf ( (char *) name,
142  "MAC: %s",
143  mac);
144 
145  if ( (0 > written)
146  || (RI_COMM_DIS_STRLEN <= written))
147  {
148  err_code |= RD_ERROR_INVALID_LENGTH;
149  }
150  else
151  {
152  err_code |= ri_nfc_address_set (name, strlen ( (char *) name));
153  }
154  }
155 
156  return err_code;
157 }
158 
159 #ifndef CEEDLING
160 static
161 #endif
162 rd_status_t id_set (const char * const id)
163 {
164  rd_status_t err_code = RD_SUCCESS;
165  int written = 0;
166 
167  if (NULL == id)
168  {
169  err_code |= RD_ERROR_NULL;
170  }
171  else
172  {
173  uint8_t id_string[RI_COMM_DIS_STRLEN] = { 0 };
174  written = snprintf ( (char *) id_string,
176  "ID: %s",
177  id);
178 
179  if ( (0 > written)
180  || (RI_COMM_DIS_STRLEN <= written))
181  {
182  err_code |= RD_ERROR_INVALID_LENGTH;
183  }
184  else
185  {
186  err_code |= ri_nfc_id_set (id_string,
187  strlen ( (char *) id_string));
188  }
189  }
190 
191  return err_code;
192 }
193 
194 rd_status_t rt_nfc_init (ri_comm_dis_init_t * const init_data)
195 {
196  rd_status_t err_code = RD_SUCCESS;
197 
198  if (NULL == init_data)
199  {
200  err_code |= RD_ERROR_NULL;
201  }
202  else if (rt_nfc_is_init())
203  {
204  err_code |= RD_ERROR_INVALID_STATE;
205  }
206  else
207  {
208  err_code |= sw_set (init_data->fw_version);
209  err_code |= mac_set (init_data->deviceaddr);
210  err_code |= id_set (init_data->deviceid);
211  err_code |= ri_nfc_init (&m_channel);
212  ri_comm_message_t msg;
213  memcpy (&msg.data, "Data:", sizeof ("Data:"));
214  msg.data_length = 6;
215  m_channel.on_evt = rt_nfc_isr;
216  err_code |= m_channel.send (&msg);
217  }
218 
219  m_nfc_is_initialized = (RD_SUCCESS == err_code);
220  return err_code;
221 }
222 
223 bool rt_nfc_is_init (void)
224 {
225  return m_nfc_is_initialized;
226 }
227 
237 {
238  m_nfc_is_initialized = false;
239  return ri_nfc_uninit (&m_channel);
240 }
241 
243 {
244  rd_status_t err_code = RD_SUCCESS;
245 
246  if (NULL == message)
247  {
248  err_code |= RD_ERROR_NULL;
249  }
250  else
251  {
252  err_code |= m_channel.send (message);
253  }
254 
255  return err_code;
256 }
257 
259 {
260  m_on_connected = cb;
261 }
262 
263 
265 {
266  m_on_disconnected = cb;
267 }
268 
270 {
271  m_on_received = cb;
272 }
273 
274 void rt_nfc_set_on_sent_isr (const ri_comm_cb_t cb)
275 {
276  m_on_sent = cb;
277 }
278 
279 bool rt_nfc_is_connected (void)
280 {
281  return m_nfc_is_connected;
282 }
283 
284 #else
285 #include "ruuvi_driver_error.h"
287 #include <stdbool.h>
289 {
290  return RD_ERROR_NOT_ENABLED;
291 }
292 
294 {
295  return RD_ERROR_NOT_ENABLED;
296 }
297 
299 {
300  // No implementation needed
301 }
302 
303 
305 {
306  // No implementation needed
307 }
308 
310 {
311  // No implementation needed
312 }
313 
315 {
316  // No implementation needed
317 }
318 
320 {
321  return false;
322 }
323 #endif
324 
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
#define RD_ERROR_INVALID_LENGTH
Invalid Length.
#define RD_ERROR_NOT_ENABLED
Driver is not enabled.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
void(* ri_comm_cb_t)(void *p_data, size_t data_len)
#define RI_COMM_DIS_STRLEN
Maximum length for device information strings.
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_address_set(const uint8_t *const address, const uint8_t length)
rd_status_t ri_nfc_init(ri_comm_channel_t *const channel)
rd_status_t ri_nfc_fw_version_set(const uint8_t *const version, const uint8_t length)
rd_status_t ri_nfc_uninit(ri_comm_channel_t *const channel)
rd_status_t ri_nfc_id_set(const uint8_t *const id, const uint8_t length)
Interface functions to scheduler.
void rt_nfc_set_on_disconn_isr(const ri_comm_cb_t cb)
Setup disconnection event handler.
bool rt_nfc_is_connected(void)
check if NFC is connected, i.e. a reader is in range. NFC data cannot be changed during connection,...
void rt_nfc_set_on_sent_isr(const ri_comm_cb_t cb)
Setup data sent event handler.
rd_status_t rt_nfc_init(ri_comm_dis_init_t *const init_data)
Initializes NFC and configures FW, ADDR and ID records according to application_config....
void rt_nfc_set_on_connected_isr(const ri_comm_cb_t cb)
Setup connection event handler.
void rt_nfc_set_on_received_isr(const ri_comm_cb_t cb)
Setup data received event handler.
rd_status_t rt_nfc_send(ri_comm_message_t *message)
Sets given message to NFC RAM buffer. Clears previous message.
NFC control.
rd_status_t rt_nfc_uninit(void)
Uninitializes NFC.
bool rt_nfc_is_init(void)
check that NFC is initialized.
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.
char deviceaddr[RI_COMM_DIS_STRLEN]
Human readable device address, e.g. MAC.
char fw_version[RI_COMM_DIS_STRLEN]
Human readable firmware version.
char deviceid[RI_COMM_DIS_STRLEN]
Human readable device ID.
Application message structure used for communication.
uint8_t data[RI_COMM_MESSAGE_MAX_LENGTH]
Data payload.
uint8_t data_length
Length of data.