Mistake on this page?
Report an issue in GitHub or email us
m24sr_driver.h
1 /* mbed Microcontroller Library
2  * SPDX-License-Identifier: BSD-3-Clause
3  ******************************************************************************
4  * @file m24sr_driver.h
5  * @author ST Central Labs
6  * @brief This file provides a set of functions to interface with the M24SR
7  * device.
8  ******************************************************************************
9  * @attention
10  *
11  * <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
12  *
13  * Redistribution and use in source and binary forms, with or without modification,
14  * are permitted provided that the following conditions are met:
15  * 1. Redistributions of source code must retain the above copyright notice,
16  * this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright notice,
18  * this list of conditions and the following disclaimer in the documentation
19  * and/or other materials provided with the distribution.
20  * 3. Neither the name of STMicroelectronics nor the names of its contributors
21  * may be used to endorse or promote products derived from this software
22  * without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  ******************************************************************************
36  */
37 
38 /*
39  Based on: X-CUBE-MEMS1/trunk/Drivers/BSP/Components/m24sr/m24sr.h
40  Revision: M24SR Driver V1.0.0
41  */
42 
43 #ifndef M24SR_H
44 #define M24SR_H
45 
46 #include <stdint.h>
47 #include <mbed.h>
48 #include "I2C.h"
49 #include "NFCEEPROMDriver.h"
50 #include "EventQueue.h"
51 
52 #if defined TARGET_DISCO_L475VG_IOT01A
53 
54 #define M24SR_I2C_SDA_PIN PB_11
55 #define M24SR_I2C_SCL_PIN PB_10
56 #define M24SR_GPO_PIN PE_4
57 #define M24SR_RF_DISABLE_PIN PE_2
58 
59 #elif MBED_CONF_X_NUCLEO_NFC01A1
60 
61 #define M24SR_I2C_SDA_PIN D14
62 #define M24SR_I2C_SCL_PIN D15
63 #define M24SR_GPO_PIN D12
64 #define M24SR_RF_DISABLE_PIN D11
65 
66 #else
67 
68 #define M24SR_I2C_SDA_PIN NC
69 #define M24SR_I2C_SCL_PIN NC
70 #define M24SR_GPO_PIN NC
71 #define M24SR_RF_DISABLE_PIN NC
72 
73 #endif
74 
75 namespace mbed {
76 namespace nfc {
77 namespace vendor {
78 namespace ST {
79 
80 #define OPEN_SESSION_RETRIES 5
81 #define CC_FILE_LENGTH 15
82 #define NDEF_FILE_HEADER_SIZE 2
83 #define MAX_NDEF_SIZE 0x1FFF
84 
85 /**
86  * User parameter used to invoke a command,
87  * it is used to provide the data back with the response
88  */
89 struct CommandData_t {
90  uint8_t *data; /**< data */
91  uint16_t length; /**< number of bytes in the data array */
92  uint16_t offset; /**< offset parameter used in the read/write command */
93 };
94 
95 /**
96  * @brief APDU Command structure
97  */
98 class C_APDU {
99 public:
100  struct C_APDUHeader_t {
101  uint8_t CLA; /**< Command class */
102  uint8_t INS; /**< Operation code */
103  uint8_t P1; /**< Selection Mode */
104  uint8_t P2; /**< Selection Option */
105  };
106 
107  struct C_APDUBody_t {
108  uint8_t LC; /**< Data field length */
109  const uint8_t *data; /**< Command parameters */
110  uint8_t LE; /**< Expected length of data to be returned */
111  };
112 
113  C_APDU(uint8_t cla, uint8_t ins, uint16_t p1p2, uint8_t length, const uint8_t *data, uint8_t expected)
114  {
115  header.CLA = cla;
116  header.INS = ins;
117  header.P1 = (uint8_t)((p1p2 & 0xFF00) >> 8);
118  header.P2 = (uint8_t)(p1p2 & 0x00FF);
119  body.LC = length;
120  body.data = data;
121  body.LE = expected;
122  }
123 
124  C_APDUHeader_t header;
125  C_APDUBody_t body;
126 };
127 
128 /**
129  * @brief SC response structure
130  */
131 struct R_APDU {
132  uint8_t *data; /**< Data returned from the card */ // pointer on the transceiver buffer = ReaderRecBuf[CR95HF_DATA_OFFSET ];
133  uint8_t SW1; /**< Command Processing status */
134  uint8_t SW2; /**< Command Processing qualification */
135 };
136 
137 enum M24srError_t : uint16_t {
138  M24SR_SUCCESS = 0,
139  M24SR_ERROR = 0x6F00,
140  M24SR_FILE_OVERFLOW_LE = 0x6280,
141  M24SR_EOF = 0x6282,
142  M24SR_PASSWORD_REQUIRED = 0x6300,
143  M24SR_PASSWORD_INCORRECT = 0x63C0,
144  M24SR_PASSWORD_INCORRECT1RETRY = 0x63C1,
145  M24SR_PASSWORD_INCORRECT2RETRY = 0x63C2,
146  M24SR_WRONG_LENGHT = 0x6700,
147  M24SR_UNSUCESSFUL_UPDATING = 0x6581,
148  M24SR_INCOPATIBLE_COMMAND = 0x6981,
149  M24SR_SECURITY_UNSATISFIED = 0x6982,
150  M24SR_REFERENCE_DATA_NOT_USABLE = 0x6984,
151 
152  M24SR_INCORRECT_PARAMETER = 0x6a80,
153  M24SR_FILE_NOT_FOUND = 0x6a82,
154  M24SR_FILE_OVERFLOW_LC = 0x6A84,
155 
156  M24SR_INCORRECT_P1_OR_P2 = 0x6A86,
157  M24SR_RF_SESSION_KILLED = 0x6500,
158  M24SR_INS_NOT_SUPPORTED = 0x6D00,
159  M24SR_CLASS_NOT_SUPPORTED = 0x6E00,
160 
161  M24SR_IO_ERROR_I2CTIMEOUT = 0x0011,
162  M24SR_IO_ERROR_CRC = 0x0012,
163  M24SR_IO_ERROR_NACK = 0x0013,
164  M24SR_IO_ERROR_PARAMETER = 0x0014,
165  M24SR_IO_ERROR_NBATEMPT = 0x0015,
166  M24SR_IO_NOACKNOWLEDGE = 0x0016,
167  M24SR_IO_PIN_NOT_CONNECTED = 0x0017
168 };
169 
170 /**
171  * @brief GPO state
172  */
173 enum NfcGpoState_t {
174  HIGH_IMPEDANCE = 0,
175  SESSION_OPENED = 1,
176  WIP = 2,
177  I2C_ANSWER_READY = 3,
178  INTERRUPT = 4,
179  STATE_CONTROL = 5
180 };
181 
182 /**
183  * Possible password to set.
184  */
185 enum PasswordType_t {
186  READ_PASSWORD = 0x01, /**< Password to use before reading the tag */
187  WRITE_PASSWORD = 0x02, /**< Password to use before writing the tag */
188  I2C_PASSWORD = 0x03, /**< Root password, used only through nfc */
189 };
190 
191 /**
192  * Command that the component can accept
193  */
194 enum Command_t {
195  NONE,
196  DESELECT,
197  SELECT_APPLICATION,
198  SELECT_CC_FILE,
199  SELECT_NDEF_FILE,
200  SELECT_SYSTEM_FILE,
201  READ,
202  UPDATE,
203  VERIFY,
204  MANAGE_I2C_GPO,
205  MANAGE_RF_GPO,
206  CHANGE_REFERENCE_DATA,
207  ENABLE_VERIFICATION_REQUIREMENT,
208  DISABLE_VERIFICATION_REQUIREMENT,
209  ENABLE_PERMANET_STATE,
210  DISABLE_PERMANET_STATE,
211 };
212 
213 /**
214  * Communication mode used by this device
215  */
216 enum Communication_t {
217  SYNC, /**< SYNC wait the command response before returning */
218  ASYNC /**< ASYNC use a callback to notify the end of a command */
219 };
220 
221 /**
222  * Class representing a M24SR component.
223  * This component has two operation modes, sync or async.
224  * In sync mode each function call returns only after the command has completed.
225  * In async mode each function call returns immediately and the answer will be notified
226  * through a callback.
227  * The default behaviour is sync mode.
228  * To enable the async mode ManageI2CGPO(I2C_ANSWER_READY) function must be called.
229  * When the component notifies an interrupt user must call {@link ManageEvent} function.
230  * Note that passing a parameter other than I2C_ANSWER_READY to ManageI2CGPO initialize the component in sync mode.
231  */
232 class M24srDriver : public NFCEEPROMDriver {
233 public:
234  /**
235  * Object that contains all the callbacks fired by this class, each command has its own callback.
236  * The callback default implementation is an empty function.
237  */
238  class Callbacks {
239  public:
240  /** called when get_session completes */
241  virtual void on_session_open(M24srDriver *nfc, M24srError_t status)
242  {
243  (void) nfc;
244  (void) status;
245  }
246 
247  /** called when deselect completes */
248  virtual void on_deselect(M24srDriver *nfc, M24srError_t status)
249  {
250  (void) nfc;
251  (void) status;
252  }
253 
254  /** called when select_application completes */
255  virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
256  {
257  (void) nfc;
258  (void) status;
259  }
260 
261  /** called when select_cc_file completes */
262  virtual void on_selected_cc_file(M24srDriver *nfc, M24srError_t status)
263  {
264  (void) nfc;
265  (void) status;
266  }
267 
268  /** called when select_ndef_file completes */
269  virtual void on_selected_ndef_file(M24srDriver *nfc, M24srError_t status)
270  {
271  (void) nfc;
272  (void) status;
273  }
274 
275  /** called when select_system_file completes */
276  virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
277  {
278  (void) nfc;
279  (void) status;
280  }
281 
282  /** called when read_binary completes */
283  virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read,
284  uint16_t read_count)
285  {
286  (void) nfc;
287  (void) status;
288  (void) offset;
289  (void) bytes_read;
290  (void) read_count;
291  }
292 
293  /** called when update_binary completes */
294  virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
295  uint16_t write_count)
296  {
297  (void) nfc;
298  (void) status;
299  (void) bytes_written;
300  (void) write_count;
301  (void) offset;
302  }
303 
304  /** called when verify completes */
305  virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t password_type, const uint8_t *pwd)
306  {
307  (void) nfc;
308  (void) status;
309  (void) password_type;
310  (void) pwd;
311  }
312 
313  /** called when manage_i2c_gpo completes */
314  virtual void on_manage_i2c_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
315  {
316  (void) nfc;
317  (void) status;
318  (void) new_status;
319  }
320 
321  /** called when manage_rf_gpo completes */
322  virtual void on_manage_rf_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
323  {
324  (void) nfc;
325  (void) status;
326  (void) new_status;
327  }
328 
329  /** called when change_reference_data completes */
330  virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type,
331  const uint8_t *data)
332  {
333  (void) nfc;
334  (void) status;
335  (void) type;
336  (void) data;
337  }
338 
339  /** called when enable_verification_requirement completes */
340  virtual void on_enable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
341  {
342  (void) nfc;
343  (void) status;
344  (void) type;
345  }
346 
347  /** called when disable_verification_requirement completes */
348  virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
349  {
350  (void) nfc;
351  (void) status;
352  (void) type;
353  }
354 
355  /** called when enable_permanent_state completes */
356  virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
357  {
358  (void) nfc;
359  (void) status;
360  (void) type;
361  }
362 
363  /** called when disable_permanent_state completes */
364  virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
365  {
366  (void) nfc;
367  (void) status;
368  (void) type;
369  }
370 
371  /** called when read_id completes */
372  virtual void on_read_id(M24srDriver *nfc, M24srError_t status, uint8_t *id)
373  {
374  (void) nfc;
375  (void) status;
376  (void) id;
377  }
378 
379  /** called when enable_read_password completes */
380  virtual void on_enable_read_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
381  {
382  (void) nfc;
383  (void) status;
384  (void) new_password;
385  }
386 
387  /** called when oenable_write_password completes */
388  virtual void on_enable_write_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
389  {
390  (void) nfc;
391  (void) status;
392  (void) new_password;
393  }
394 
395  /** called when disable_read_password completes */
396  virtual void on_disable_read_password(M24srDriver *nfc, M24srError_t status)
397  {
398  (void) nfc;
399  (void) status;
400  }
401 
402  /** called when disable_write_password completes */
403  virtual void on_disable_write_password(M24srDriver *nfc, M24srError_t status)
404  {
405  (void) nfc;
406  (void) status;
407  }
408 
409  /** called when disable_all_password completes */
410  virtual void on_disable_all_password(M24srDriver *nfc, M24srError_t status)
411  {
412  (void) nfc;
413  (void) status;
414  }
415 
416  /** called when enable_read_only completes */
417  virtual void on_enable_read_only(M24srDriver *nfc, M24srError_t status)
418  {
419  (void) nfc;
420  (void) status;
421  }
422 
423  /** called when enable_write_only completes */
424  virtual void on_enable_write_only(M24srDriver *nfc, M24srError_t status)
425  {
426  (void) nfc;
427  (void) status;
428  }
429 
430  /** called when disable_read_only completes */
431  virtual void on_disable_read_only(M24srDriver *nfc, M24srError_t status)
432  {
433  (void) nfc;
434  (void) status;
435  }
436 
437  /** called when disable_write_only completes */
438  virtual void on_disable_write_only(M24srDriver *nfc, M24srError_t status)
439  {
440  (void) nfc;
441  (void) status;
442  }
443 
444  virtual ~Callbacks() { }
445  };
446 
447 public:
448  /** Create the driver, default pin names will be used appropriate for the board.
449  * @param i2c_data_pin I2C data pin name.
450  * @param i2c_clock_pin I2C clock pin name.
451  * @param gpo_pin I2C GPO pin name.
452  * @param rf_disable_pin pin name for breaking the RF connection.
453  */
454  M24srDriver(PinName i2c_data_pin = M24SR_I2C_SDA_PIN, PinName i2c_clock_pin = M24SR_I2C_SCL_PIN,
455  PinName gpo_pin = M24SR_GPO_PIN, PinName rf_disable_pin = M24SR_RF_DISABLE_PIN);
456 
457  virtual ~M24srDriver() { }
458 
459  /** @see NFCEEPROMDriver::reset
460  */
461  virtual void reset()
462  {
463  set_callback(&_default_cb);
464  init();
465  manage_i2c_gpo(I2C_ANSWER_READY);
466  }
467 
468  /** @see NFCEEPROMDriver::get_max_size
469  */
470  virtual size_t read_max_size()
471  {
472  return MAX_NDEF_SIZE;
473  }
474 
475  /** @see NFCEEPROMDriver::start_session
476  */
477  virtual void start_session(bool force = true)
478  {
479  if (_is_session_open) {
480  delegate()->on_session_started(true);
481  return;
482  }
483 
484  set_callback(&_open_session_cb);
485 
486  get_session(force);
487  }
488 
489  /** @see NFCEEPROMDriver::end_session
490  */
491  virtual void end_session()
492  {
493  set_callback(&_close_session_cb);
494  deselect();
495  }
496 
497  /** @see NFCEEPROMDriver::read_bytes
498  */
499  virtual void read_bytes(uint32_t address, uint8_t *bytes, size_t count)
500  {
501  if (!_is_session_open) {
502  delegate()->on_bytes_read(0);
503  return;
504  }
505 
506  if (address > _ndef_size) {
507  delegate()->on_bytes_read(0);
508  return;
509  }
510 
511  set_callback(&_read_byte_cb);
512 
513  if (count > _max_read_bytes) {
514  count = _max_read_bytes;
515  }
516 
517  if (address + count > _ndef_size) {
518  count = _ndef_size - address;
519  }
520 
521  if (count == 0) {
522  delegate()->on_bytes_read(0);
523  return;
524  }
525 
526  /* offset by ndef file size*/
527  address += NDEF_FILE_HEADER_SIZE;
528 
529  read_binary((uint16_t) address, (uint8_t) count, bytes);
530  }
531 
532  /** @see NFCEEPROMDriver::write_bytes
533  */
534  virtual void write_bytes(uint32_t address, const uint8_t *bytes, size_t count)
535  {
536  if (!_is_session_open) {
537  delegate()->on_bytes_written(0);
538  return;
539  }
540 
541  if (address > _ndef_size) {
542  delegate()->on_bytes_written(0);
543  return;
544  }
545 
546  if (bytes) {
547  set_callback(&_write_byte_cb);
548  } else {
549  set_callback(&_erase_bytes_cb);
550  }
551 
552  if (count > _max_write_bytes) {
553  count = _max_write_bytes;
554  }
555 
556  if (address + count > _ndef_size) {
557  count = _ndef_size - address;
558  }
559 
560  if (count == 0) {
561  delegate()->on_bytes_written(0);
562  return;
563  }
564 
565  /* offset by ndef file size*/
566  address += NDEF_FILE_HEADER_SIZE;
567 
568  update_binary((uint16_t) address, (uint8_t) count, bytes);
569  }
570 
571  /** @see NFCEEPROMDriver::set_size
572  */
573  virtual void write_size(size_t count)
574  {
575  if (!_is_session_open) {
576  delegate()->on_size_read(false, 0);
577  return;
578  }
579 
580  if (count > MAX_NDEF_SIZE - NDEF_FILE_HEADER_SIZE) {
581  delegate()->on_size_read(false, 0);
582  return;
583  }
584 
585  set_callback(&_set_size_cb);
586 
587  _ndef_size = (uint16_t)count;
588 
589  /* NDEF file size is BE */
590  uint8_t *bytes = (uint8_t *)&_ndef_size;
591  _ndef_size_buffer[0] = bytes[1];
592  _ndef_size_buffer[1] = bytes[0];
593 
594  update_binary(0, NDEF_FILE_HEADER_SIZE, (const uint8_t *)&_ndef_size_buffer);
595  }
596 
597  /** @see NFCEEPROMDriver::get_size
598  */
599  virtual void read_size()
600  {
601  if (!_is_session_open) {
602  delegate()->on_size_read(false, 0);
603  return;
604  }
605 
606  set_callback(&_get_size_cb);
607 
608  read_binary(0, NDEF_FILE_HEADER_SIZE, (uint8_t *)&_ndef_size_buffer);
609  }
610 
611  /** @see NFCEEPROMDriver::erase_bytes
612  */
613  virtual void erase_bytes(uint32_t address, size_t size)
614  {
615  write_bytes(address, NULL, size);
616  }
617 
618 private:
619  /**
620  * Change the function to call when a command ends.
621  * @param commandCallback Object containing the callback, if NULL it will use empty callback
622  */
623  void set_callback(Callbacks *callback)
624  {
625  if (callback) {
626  _command_cb = callback;
627  } else {
628  _command_cb = &_default_cb;
629  }
630  }
631 
632  /**
633  * get the callback object to use
634  * @return callback object to use
635  */
636  Callbacks *get_callback()
637  {
638  /* this allows for two levels of operation, the previous command will continue
639  * when this set of callbacks has finished */
640  if (_subcommand_cb) {
641  return _subcommand_cb;
642  }
643  return _command_cb;
644  }
645 
646  void nfc_interrupt_callback()
647  {
648  if (_communication_type == ASYNC) {
649  event_queue()->call(this, &M24srDriver::manage_event);
650  }
651  }
652 
653  /**
654  * Enable the request of a password before reading the tag.
655  * @param current_write_password Current password
656  * @param new_password Password to request before reading the tag.
657  * @return return M24SR_SUCCESS if no errors
658  * @note The password must have a length of 16 chars.
659  */
660  M24srError_t enable_read_password(const uint8_t *current_write_password, const uint8_t *new_password)
661  {
662  _subcommand_cb = &_change_password_request_status_cb;
663  _change_password_request_status_cb.set_task(READ_PASSWORD, new_password);
664 
665  return verify(WRITE_PASSWORD, current_write_password);
666  }
667 
668  /**
669  * Disable the request of a password before reading the tag.
670  * @param current_write_password Current password
671  * @return return M24SR_SUCCESS if no errors
672  * @note The password must have a length of 16 chars.
673  */
674  M24srError_t disable_read_password(const uint8_t *current_write_password)
675  {
676  _subcommand_cb = &_change_password_request_status_cb;
677  _change_password_request_status_cb.set_task(READ_PASSWORD, NULL);
678 
679  return verify(WRITE_PASSWORD, current_write_password);
680  }
681 
682  /**
683  * Enable the request of a password before writing to the tag.
684  * @param current_write_password Current password
685  * @param new_password Password to request before reading the tag.
686  * @return return M24SR_SUCCESS if no errors
687  * @note The password must have a length of 16 chars.
688  */
689  M24srError_t enable_write_password(const uint8_t *current_write_password, uint8_t *new_password)
690  {
691  _subcommand_cb = &_change_password_request_status_cb;
692  _change_password_request_status_cb.set_task(WRITE_PASSWORD, new_password);
693 
694  return verify(WRITE_PASSWORD, current_write_password);
695  }
696 
697  /**
698  * Disable the request of a password before writing the tag.
699  * @param current_write_password Current password.
700  * @return return M24SR_SUCCESS if no errors
701  * @note The password must have a length of 16 chars.
702  */
703  M24srError_t disable_write_password(const uint8_t *current_write_password)
704  {
705  _subcommand_cb = &_change_password_request_status_cb;
706  _change_password_request_status_cb.set_task(WRITE_PASSWORD, NULL);
707 
708  return verify(WRITE_PASSWORD, current_write_password);
709  }
710 
711  /**
712  * @brief This function disables both read and write passwords.
713  * @param super_user_password I2C super user password.
714  * @return return M24SR_SUCCESS if no errors
715  * @note The password must have a length of 16 chars.
716  */
717  M24srError_t disable_all_password(const uint8_t *super_user_password)
718  {
719  _subcommand_cb = &_remove_password_cb;
720  return verify(I2C_PASSWORD, super_user_password);
721  }
722 
723  /**
724  * @brief This function enables read only mode.
725  * @param current_write_password Write password is needed to enable read only mode.
726  * @return return M24SR_SUCCESS if no errors
727  * @note The password must have a length of 16 chars.
728  */
729  M24srError_t enable_read_only(const uint8_t *current_write_password)
730  {
731  _subcommand_cb = &_change_access_state_cb;
732  _change_access_state_cb.change_access_state(ChangeAccessStateCallback::WRITE, false);
733 
734  return verify(WRITE_PASSWORD, current_write_password);
735  }
736 
737  /**
738  * @brief This function disables read only mode.
739  * @param current_write_password Write password is needed to disable read only mode.
740  * @return return M24SR_SUCCESS if no errors
741  * @note The password must have a length of 16 chars.
742  */
743  M24srError_t disable_read_only(const uint8_t *current_write_password)
744  {
745  _subcommand_cb = &_change_access_state_cb;
746  _change_access_state_cb.change_access_state(ChangeAccessStateCallback::WRITE, true);
747 
748  return verify(I2C_PASSWORD, current_write_password);
749  }
750 
751  /**
752  * @brief This function enables write only mode.
753  * @param current_write_password Write password is needed to enable write only mode.
754  * @return return M24SR_SUCCESS if no errors
755  * @note The password must have a length of 16 chars.
756  */
757  M24srError_t enable_write_only(const uint8_t *current_write_password)
758  {
759  _subcommand_cb = &_change_access_state_cb;
760  _change_access_state_cb.change_access_state(ChangeAccessStateCallback::READ, false);
761 
762  return verify(WRITE_PASSWORD, current_write_password);
763  }
764 
765  /**
766  * @brief This function disables write only mode.
767  * @param current_write_password Write password is needed to disable write only mode.
768  * @return return M24SR_SUCCESS if no errors
769  * @note The password must have a length of 16 chars.
770  */
771  M24srError_t disable_write_only(const uint8_t *current_write_password)
772  {
773  _subcommand_cb = &_change_access_state_cb;
774  _change_access_state_cb.change_access_state(ChangeAccessStateCallback::READ, true);
775 
776  return verify(I2C_PASSWORD, current_write_password);
777  }
778 
779 private:
780  M24srError_t init();
781  M24srError_t read_id(uint8_t *nfc_id);
782  M24srError_t get_session(bool force = false);
783 
784  M24srError_t deselect();
785  M24srError_t receive_deselect();
786 
787  M24srError_t select_application();
788  M24srError_t receive_select_application();
789 
790  M24srError_t select_cc_file();
791  M24srError_t receive_select_cc_file();
792 
793  M24srError_t select_ndef_file(uint16_t ndef_file_id);
794  M24srError_t receive_select_ndef_file();
795 
796  M24srError_t select_system_file();
797  M24srError_t receive_select_system_file();
798 
799  M24srError_t read_binary(uint16_t offset, uint8_t length, uint8_t *buffer);
800  M24srError_t st_read_binary(uint16_t offset, uint8_t length, uint8_t *buffer);
801  M24srError_t receive_read_binary();
802 
803  M24srError_t update_binary(uint16_t offset, uint8_t length, const uint8_t *data);
804  M24srError_t receive_update_binary();
805 
806  M24srError_t verify(PasswordType_t password_type, const uint8_t *password);
807  M24srError_t receive_verify();
808 
809  M24srError_t change_reference_data(PasswordType_t password_type, const uint8_t *password);
810  M24srError_t receive_change_reference_data();
811 
812  M24srError_t enable_verification_requirement(PasswordType_t password_type);
813  M24srError_t receive_enable_verification_requirement();
814 
815  M24srError_t disable_verification_requirement(PasswordType_t password_type);
816  M24srError_t receive_disable_verification_requirement();
817 
818  M24srError_t enable_permanent_state(PasswordType_t password_type);
819  M24srError_t receive_enable_permanent_state();
820 
821  M24srError_t disable_permanent_state(PasswordType_t password_type);
822  M24srError_t receive_disable_permanent_state();
823 
824  M24srError_t send_interrupt();
825  M24srError_t state_control(bool gpo_reset);
826 
827  M24srError_t manage_i2c_gpo(NfcGpoState_t gpo_i2c_config);
828  M24srError_t manage_rf_gpo(NfcGpoState_t gpo_rf_config);
829 
830  M24srError_t rf_config(bool enable);
831  M24srError_t send_fwt_extension(uint8_t fwt_byte);
832 
833  M24srError_t send_receive_i2c(uint16_t length, uint8_t *command);
834 
835  /**
836  * Function to call when the component fire an interrupt.
837  * @return last operation status
838  */
839  M24srError_t manage_event();
840 
841  /**
842  * Send a command to the component.
843  * @param length Length of the command.
844  * @param command Buffer containing the command.
845  * @return M24SR_SUCCESS if no errors
846  */
847  M24srError_t io_send_i2c_command(uint8_t length, const uint8_t *command);
848 
849  /**
850  * Read a command response.
851  * @param length Number of bytes to read.
852  * @param command Buffer to store the response into.
853  * @return M24SR_SUCCESS if no errors
854  */
855  M24srError_t io_receive_i2c_response(uint8_t length, uint8_t *command);
856 
857  /**
858  * Do an active polling on the I2C bus until the answer is ready.
859  * @return M24SR_SUCCESS if no errors
860  */
861  M24srError_t io_poll_i2c();
862 
863  bool manage_sync_communication(M24srError_t *status);
864 
865 private:
866  /**
867  * @brief This class permits to enable/disable the password request to read/write into the tag
868  */
869  class ChangePasswordRequestStatusCallback : public Callbacks {
870  public:
871  /**
872  * Build the chain of callbacks.
873  */
874  ChangePasswordRequestStatusCallback()
875  : _new_password(NULL),
876  _type(I2C_PASSWORD),
877  _enable(false) { }
878 
879  /* This class is equivalent to calling the methods:
880  *
881  * To enable the request:
882  * - Verify
883  * - change_reference_data
884  * - enable_permanent_state
885  *
886  * To disable the request:
887  * - verify
888  * - disable_verification_requirement
889  */
890 
891  /**
892  * Set the password to enable/disable.
893  * @param type Type of password to enable/disable.
894  * @param new_password Array of 16bytes with the new password, if null the request will be disabled.
895  */
896  void set_task(PasswordType_t type, const uint8_t *new_password)
897  {
898  _new_password = new_password;
899  _type = type;
900  _enable = (new_password != NULL);
901  }
902 
903  virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *)
904  {
905  if (status != M24SR_SUCCESS) {
906  return on_finish_command(nfc, status);
907  }
908  if (_enable) {
909  nfc->change_reference_data(_type, _new_password);
910  } else {
911  nfc->disable_verification_requirement(_type);
912  }
913  }
914 
915  virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t)
916  {
917  on_finish_command(nfc, status);
918  }
919 
920  virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type, const uint8_t *)
921  {
922  if (status == M24SR_SUCCESS) {
923  nfc->enable_permanent_state(type);
924  } else {
925  on_finish_command(nfc, status);
926  }
927  }
928 
929  virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t)
930  {
931  on_finish_command(nfc, status);
932  }
933 
934  private:
935  /**
936  * Remove the private callbacks and call the user callback.
937  * @param nfc Object triggering the command.
938  * @param status Command status.
939  */
940  void on_finish_command(M24srDriver *nfc, M24srError_t status)
941  {
942  nfc->_subcommand_cb = NULL;
943 
944  if (_enable) {
945  if (_type == READ_PASSWORD) {
946  nfc->get_callback()->on_enable_read_password(nfc, status, _new_password);
947  } else {
948  nfc->get_callback()->on_enable_write_password(nfc, status, _new_password);
949  }
950  } else {
951  if (_type == READ_PASSWORD) {
952  nfc->get_callback()->on_disable_read_password(nfc, status);
953  } else {
954  nfc->get_callback()->on_disable_write_password(nfc, status);
955  }
956  }
957  }
958 
959  private:
960  const uint8_t *_new_password;
961  PasswordType_t _type;
962  bool _enable;
963  };
964 
965  /**
966  * @brief This class permits to disable all the password requests to read/write into the tag.
967  */
968  class RemoveAllPasswordCallback : public Callbacks {
969  public:
970  /**
971  * Build the chain of callbacks.
972  */
973  RemoveAllPasswordCallback()
974  : _password(NULL) { }
975 
976  /* This class is equivalent to calling the methods:
977  * - verify(i2c)
978  * - disable_permanent_state(Read)
979  * - disable_permanent_state(write)
980  * - disable_verification_requirement(Read)
981  * - disable_verification_requirement(write)
982  * - change_reference_data(Read)
983  * - change_reference_data(write)
984  */
985 
986  virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *data)
987  {
988  if (status != M24SR_SUCCESS) {
989  return on_finish_command(nfc, status);
990  }
991  _password = data;
992  nfc->disable_permanent_state(READ_PASSWORD);
993  }
994 
995  virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
996  {
997  if (status != M24SR_SUCCESS) {
998  return on_finish_command(nfc, status);
999  }
1000  if (type == READ_PASSWORD) {
1001  nfc->disable_permanent_state(WRITE_PASSWORD);
1002  } else {
1003  nfc->disable_verification_requirement(READ_PASSWORD);
1004  }
1005  }
1006 
1007  virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
1008  {
1009  if (status != M24SR_SUCCESS) {
1010  return on_finish_command(nfc, status);
1011  }
1012  if (type == READ_PASSWORD) {
1013  nfc->disable_verification_requirement(WRITE_PASSWORD);
1014  } else {
1015  nfc->change_reference_data(READ_PASSWORD, _password);
1016  }
1017  }
1018 
1019  virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type,
1020  const uint8_t *data)
1021  {
1022  if (status != M24SR_SUCCESS) {
1023  return on_finish_command(nfc, status);
1024  }
1025  if (type == READ_PASSWORD) {
1026  nfc->change_reference_data(WRITE_PASSWORD, data);
1027  } else {
1028  on_finish_command(nfc, status);
1029  }
1030  }
1031 
1032  private:
1033  /**
1034  * Remove the private callback and call the onDisableAllPassword callback.
1035  * @param nfc Object triggering the command.
1036  * @param status Command status.
1037  */
1038  void on_finish_command(M24srDriver *nfc, M24srError_t status)
1039  {
1040  nfc->_subcommand_cb = NULL;
1041  _password = NULL;
1042  nfc->get_callback()->on_disable_all_password(nfc, status);
1043  }
1044 
1045  private:
1046  /**
1047  * Store the default password used for open a super user session
1048  * it will be set as default read/write password
1049  */
1050  const uint8_t *_password;
1051  };
1052 
1053  /**
1054  * @brief This class permits to set the tag as read/write only.
1055  */
1056  class ChangeAccessStateCallback : public Callbacks {
1057  public:
1058  enum AccessType_t {
1059  WRITE,
1060  READ
1061  };
1062 
1063  /**
1064  * Build the chain of callbacks.
1065  */
1066  ChangeAccessStateCallback()
1067  : _type(WRITE),
1068  _enable(false) { }
1069 
1070  /* This class is equivalent to calling the methods:
1071  * - verify(i2c)
1072  * - enable_permanent_state(Read/write)
1073  * or:
1074  * - verify(i2c)
1075  * - disable_permanent_state</li>
1076  * - disable_verification_requirement(Read/write)
1077  */
1078 
1079  /**
1080  * Set the access to enable/disable an access type.
1081  * @param type Access type.
1082  * @param enable True to enable the state, False to disable it.
1083  */
1084  void change_access_state(AccessType_t type, bool enable)
1085  {
1086  _type = type;
1087  _enable = enable;
1088  }
1089 
1090  virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *)
1091  {
1092  if (status != M24SR_SUCCESS) {
1093  return on_finish_command(nfc, status);
1094  }
1095 
1096  if (_enable) {
1097  nfc->disable_permanent_state(_type == WRITE ? WRITE_PASSWORD : READ_PASSWORD);
1098  } else {
1099  nfc->enable_permanent_state(_type == WRITE ? WRITE_PASSWORD : READ_PASSWORD);
1100  }
1101 
1102  }
1103 
1104  virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
1105  {
1106  if (status != M24SR_SUCCESS) {
1107  return on_finish_command(nfc, status);
1108  }
1109 
1110  nfc->disable_verification_requirement(type);
1111  }
1112 
1113  virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t)
1114  {
1115  on_finish_command(nfc, status);
1116  }
1117 
1118  virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t)
1119  {
1120  on_finish_command(nfc, status);
1121  }
1122 
1123  private:
1124  /**
1125  * Remove the private callback and call the user callback.
1126  * @param nfc Object triggering the command.
1127  * @param status Command status.
1128  */
1129  void on_finish_command(M24srDriver *nfc, M24srError_t status)
1130  {
1131  nfc->_subcommand_cb = NULL;
1132  if (_enable) {
1133  if (_type == READ) {
1134  //enable read = disable write only
1135  nfc->get_callback()->on_disable_write_only(nfc, status);
1136  } else {
1137  //enable write = disable read only
1138  nfc->get_callback()->on_disable_read_only(nfc, status);
1139  }
1140  } else {
1141  if (_type == WRITE) {
1142  //disable write = enable read only
1143  nfc->get_callback()->on_enable_read_only(nfc, status);
1144  } else {
1145  nfc->get_callback()->on_enable_write_only(nfc, status);
1146  }
1147  }
1148  }
1149 
1150  private:
1151  AccessType_t _type;
1152  bool _enable;
1153  };
1154 
1155  /**
1156  * @brief Object with the callback used to send a ManageGPO command.
1157  */
1158  class ManageGPOCallback : public Callbacks {
1159 
1160  public:
1161  /**
1162  * Build the chain of callbacks.
1163  * @param parent Parent component to run the command on.
1164  */
1165  ManageGPOCallback()
1166  : _new_gpo_config(HIGH_IMPEDANCE),
1167  _read_gpo_config(0),
1168  _change_i2c_gpo(true) { }
1169 
1170  /* This class is equivalent to calling the methods:
1171  * - selected_application
1172  * - select_system_file
1173  * - read_binary
1174  * - verify
1175  * - update_binary
1176  */
1177 
1178  /**
1179  * Command parameters.
1180  * @param i2cGpo true to change the i2c gpo, false for the rf gpo.
1181  * @param new_config new gpo function.
1182  */
1183  void set_new_gpo_config(bool i2cGpo, NfcGpoState_t new_config)
1184  {
1185  _new_gpo_config = new_config;
1186  _change_i2c_gpo = i2cGpo;
1187  }
1188 
1189  virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
1190  {
1191  if (status == M24SR_SUCCESS) {
1192  nfc->select_system_file();
1193  } else {
1194  on_finish_command(nfc, status);
1195  }
1196  }
1197 
1198  virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
1199  {
1200  if (status == M24SR_SUCCESS) {
1201  nfc->read_binary(0x0004, 0x01, &_read_gpo_config);
1202  } else {
1203  on_finish_command(nfc, status);
1204  }
1205  }
1206 
1207  virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *, uint16_t)
1208  {
1209  if (status == M24SR_SUCCESS) {
1210  nfc->verify(I2C_PASSWORD, default_password);
1211  } else {
1212  on_finish_command(nfc, status);
1213  }
1214  }
1215 
1216  virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t, const uint8_t *)
1217  {
1218  if (status != M24SR_SUCCESS) {
1219  return on_finish_command(nfc, status);
1220  }
1221 
1222  if (_change_i2c_gpo) {
1223  _read_gpo_config = (_read_gpo_config & 0xF0) | (uint8_t) _new_gpo_config;
1224  } else {
1225  _read_gpo_config = (_read_gpo_config & 0x0F) | (((uint8_t) _new_gpo_config) << 4);
1226  }
1227 
1228  nfc->update_binary(0x0004, 0x01, &_read_gpo_config);
1229  }
1230 
1231  virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *, uint16_t)
1232  {
1233 
1234  if (status == M24SR_SUCCESS) {
1235  if (_new_gpo_config == I2C_ANSWER_READY) {
1236  nfc->_communication_type = ASYNC;
1237  } else {
1238  nfc->_communication_type = SYNC;
1239  }
1240  }
1241  on_finish_command(nfc, status);
1242  }
1243 
1244  private:
1245  /**
1246  * Remove the private callback and call the user callback.
1247  * @param nfc Object where the command was send to.
1248  * @param status Command status.
1249  */
1250  void on_finish_command(M24srDriver *nfc, M24srError_t status)
1251  {
1252  nfc->_subcommand_cb = NULL;
1253  if (_change_i2c_gpo) {
1254  nfc->_command_cb->on_manage_i2c_gpo(nfc, status, _new_gpo_config);
1255  } else {
1256  nfc->_command_cb->on_manage_rf_gpo(nfc, status, _new_gpo_config);
1257  }
1258  }
1259 
1260  private:
1261  /** new gpo function that this class has to write */
1262  NfcGpoState_t _new_gpo_config;
1263 
1264  /** variable where storeing the read gpo configuration */
1265  uint8_t _read_gpo_config;
1266 
1267  /** true to change the i2c gpo, false to change the rf gpo */
1268  bool _change_i2c_gpo;
1269  };
1270 
1271  /**
1272  * @brief Object with the callback used to read the component ID
1273  */
1274  class ReadIDCallback : public Callbacks {
1275  public:
1276  /**
1277  * Build the chain of callbacks.
1278  * @param parent object where to send the command to.
1279  */
1280  ReadIDCallback() : _id(NULL) { }
1281 
1282  /* This class is equivalent to calling the methods:
1283  * - select_application
1284  * - select_system_file
1285  * - read_binary
1286  */
1287 
1288  /**
1289  * Set the variable containing the result
1290  * @param idPtr
1291  */
1292  void set_task(uint8_t *id)
1293  {
1294  _id = id;
1295  }
1296 
1297  virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
1298  {
1299  if (status == M24SR_SUCCESS) {
1300  nfc->select_system_file();
1301  } else {
1302  on_finish_command(nfc, status);
1303  }
1304 
1305  }
1306 
1307  virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
1308  {
1309  if (status == M24SR_SUCCESS) {
1310  nfc->read_binary(0x0011, 0x01, _id);
1311  } else {
1312  on_finish_command(nfc, status);
1313  }
1314  }
1315 
1316  virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *, uint16_t)
1317  {
1318  on_finish_command(nfc, status);
1319  }
1320 
1321  private:
1322  /**
1323  * Remove the private callback and call the user onReadId function.
1324  * @param nfc Object where the command was send.
1325  * @param status Command status.
1326  */
1327  void on_finish_command(M24srDriver *nfc, M24srError_t status)
1328  {
1329  nfc->_subcommand_cb = NULL;
1330  nfc->get_callback()->on_read_id(nfc, status, _id);
1331  }
1332 
1333  private:
1334  /** pointer to read id */
1335  uint8_t *_id;
1336  };
1337 
1338  /**
1339  * Class containing the callback needed to open a session and read the max
1340  * read/write size
1341  */
1342  class OpenSessionCallBack : public Callbacks {
1343  public:
1344  OpenSessionCallBack()
1345  : _retries(OPEN_SESSION_RETRIES) { }
1346 
1347  void on_session_open(M24srDriver *nfc, M24srError_t status)
1348  {
1349  if (status == M24SR_SUCCESS) {
1350  nfc->select_application();
1351  } else {
1352  nfc->delegate()->on_session_started(false);
1353  }
1354  }
1355 
1356  void on_selected_application(M24srDriver *nfc, M24srError_t status)
1357  {
1358  if (status == M24SR_SUCCESS) {
1359  nfc->select_cc_file();
1360  } else {
1361  if (_retries == 0) {
1362  nfc->delegate()->on_session_started(false);
1363  } else {
1364  _retries--;
1365  nfc->select_application();
1366  }
1367  }
1368  }
1369 
1370  void on_selected_cc_file(M24srDriver *nfc, M24srError_t status)
1371  {
1372  if (status == M24SR_SUCCESS) {
1373  nfc->read_binary(0x0000, CC_FILE_LENGTH, CCFile);
1374  } else {
1375  nfc->delegate()->on_session_started(false);
1376  }
1377  }
1378 
1379  void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t, uint8_t *bytes_read,
1380  uint16_t read_count)
1381  {
1382  if (status != M24SR_SUCCESS || read_count != CC_FILE_LENGTH) {
1383  nfc->delegate()->on_session_started(false);
1384  }
1385  uint16_t ndef_file_id = (uint16_t)((bytes_read[0x09] << 8) | bytes_read[0x0A]);
1386  nfc->_max_read_bytes = (uint16_t)((bytes_read[0x03] << 8) | bytes_read[0x04]);
1387  nfc->_max_write_bytes = (uint16_t)((bytes_read[0x05] << 8) | bytes_read[0x06]);
1388  nfc->select_ndef_file(ndef_file_id);
1389  }
1390 
1391  void on_selected_ndef_file(M24srDriver *nfc, M24srError_t status)
1392  {
1393  nfc->_is_session_open = (status == M24SR_SUCCESS);
1394  nfc->delegate()->on_session_started(nfc->_is_session_open);
1395  }
1396 
1397  private:
1398  /** number of trials done for open the session */
1399  uint32_t _retries;
1400 
1401  /** buffer where read the CC file */
1402  uint8_t CCFile[15];
1403  };
1404 
1405  /**
1406  * Class containing the callback needed to close a session
1407  */
1408  class CloseSessionCallBack : public Callbacks {
1409  public:
1410  CloseSessionCallBack() { }
1411 
1412  virtual void on_deselect(M24srDriver *nfc, M24srError_t status)
1413  {
1414  if (status == M24SR_SUCCESS) {
1415  nfc->_is_session_open = false;
1416  nfc->delegate()->on_session_ended(true);
1417  } else {
1418  nfc->delegate()->on_session_ended(false);
1419  }
1420  }
1421  };
1422 
1423  /**
1424  * Class containing the callback needed to write a buffer
1425  */
1426  class WriteByteCallback : public Callbacks {
1427  public:
1428  WriteByteCallback() { }
1429 
1430  virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
1431  uint16_t write_count)
1432  {
1433  if (status != M24SR_SUCCESS) {
1434  nfc->delegate()->on_bytes_written(0);
1435  return;
1436  }
1437 
1438  nfc->delegate()->on_bytes_written(write_count);
1439  }
1440  };
1441 
1442  /**
1443  * Class containing the callback needed to read a buffer
1444  */
1445  class ReadByteCallback : public Callbacks {
1446  public:
1447  ReadByteCallback() { }
1448 
1449  virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read,
1450  uint16_t read_count)
1451  {
1452  if (status != M24SR_SUCCESS) {
1453  nfc->delegate()->on_bytes_read(0);
1454  return;
1455  }
1456 
1457  nfc->delegate()->on_bytes_read(read_count);
1458  }
1459  };
1460 
1461  class SetSizeCallback : public Callbacks {
1462  public:
1463  SetSizeCallback() { }
1464 
1465  virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
1466  uint16_t write_count)
1467  {
1468  if (status != M24SR_SUCCESS) {
1469  nfc->delegate()->on_size_written(false);
1470  return;
1471  }
1472 
1473  nfc->delegate()->on_size_written(true);
1474  }
1475  };
1476 
1477  class GetSizeCallback : public Callbacks {
1478  public:
1479  GetSizeCallback() { }
1480 
1481  virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read,
1482  uint16_t read_count)
1483  {
1484  if (status != M24SR_SUCCESS) {
1485  nfc->delegate()->on_size_read(false, 0);
1486  return;
1487  }
1488 
1489  /* NDEF file size is BE */
1490  nfc->_ndef_size = (((uint16_t) nfc->_ndef_size_buffer[0]) << 8 | nfc->_ndef_size_buffer[1]);
1491 
1492  nfc->delegate()->on_size_read(true, nfc->_ndef_size);
1493  }
1494  };
1495 
1496  class EraseBytesCallback : public Callbacks {
1497  public:
1498  EraseBytesCallback() { }
1499 
1500  virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written,
1501  uint16_t write_count)
1502  {
1503  if (status != M24SR_SUCCESS) {
1504  nfc->delegate()->on_bytes_erased(0);
1505  return;
1506  }
1507 
1508  nfc->delegate()->on_bytes_erased(write_count);
1509  }
1510  };
1511 
1512 private:
1513  /** Default password used to change the write/read permission */
1514  static const uint8_t default_password[16];
1515 
1516  I2C _i2c_channel;
1517 
1518  /** Interrupt object fired when the gpo status changes */
1519  InterruptIn _gpo_event_interrupt;
1520  DigitalIn _gpo_pin;
1521  DigitalOut _rf_disable_pin;
1522 
1523  /** object containing the callbacks to use*/
1524  Callbacks *_command_cb;
1525 
1526  /**
1527  * Object with private callbacks used to hide high level commands each
1528  * calling multiple low level commands. This callbacks object has
1529  * higher priority comparing to the user callbacks.
1530  */
1531  Callbacks *_subcommand_cb;
1532 
1533  Callbacks _default_cb;
1534  ManageGPOCallback _manage_gpo_cb;
1535  ReadIDCallback _read_id_cb;
1536  ChangePasswordRequestStatusCallback _change_password_request_status_cb;
1537  RemoveAllPasswordCallback _remove_password_cb;
1538  ChangeAccessStateCallback _change_access_state_cb;
1539  OpenSessionCallBack _open_session_cb;
1540  CloseSessionCallBack _close_session_cb;
1541  WriteByteCallback _write_byte_cb;
1542  ReadByteCallback _read_byte_cb;
1543  SetSizeCallback _set_size_cb;
1544  GetSizeCallback _get_size_cb;
1545  EraseBytesCallback _erase_bytes_cb;
1546 
1547 
1548  uint8_t _buffer[0xFF];
1549 
1550  /** Type of communication being used (SYNC, ASYNC) */
1551  Communication_t _communication_type;
1552 
1553  Command_t _last_command;
1554  CommandData_t _last_command_data;
1555 
1556  /** Buffer used to build the command to send to the chip. */
1557  uint16_t _ndef_size;
1558  uint8_t _ndef_size_buffer[NDEF_FILE_HEADER_SIZE];
1559  uint8_t _max_read_bytes;
1560  uint8_t _max_write_bytes;
1561  uint8_t _did_byte;
1562 
1563  bool _is_session_open;
1564 };
1565 
1566 } //ST
1567 } //vendor
1568 } //nfc
1569 } //mbed
1570 
1571 #endif // M24SR_H
1572 
1573 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
virtual void on_disable_write_password(M24srDriver *nfc, M24srError_t status)
called when disable_write_password completes
Definition: m24sr_driver.h:403
virtual void on_selected_system_file(M24srDriver *nfc, M24srError_t status)
called when select_system_file completes
Definition: m24sr_driver.h:276
virtual void on_disable_write_only(M24srDriver *nfc, M24srError_t status)
called when disable_write_only completes
Definition: m24sr_driver.h:438
SC response structure.
Definition: m24sr_driver.h:131
virtual void on_session_ended(bool success)=0
Completion of session end operation.
virtual void erase_bytes(uint32_t address, size_t size)
Definition: m24sr_driver.h:613
virtual void on_enable_write_only(M24srDriver *nfc, M24srError_t status)
called when enable_write_only completes
Definition: m24sr_driver.h:424
virtual void on_session_started(bool success)=0
Completion of session start operation.
virtual void on_deselect(M24srDriver *nfc, M24srError_t status)
called when deselect completes
Definition: m24sr_driver.h:248
virtual void on_size_written(bool success)=0
Completion of size setting operation.
virtual void on_disable_read_password(M24srDriver *nfc, M24srError_t status)
called when disable_read_password completes
Definition: m24sr_driver.h:396
virtual void on_selected_ndef_file(M24srDriver *nfc, M24srError_t status)
called when select_ndef_file completes
Definition: m24sr_driver.h:269
Object that contains all the callbacks fired by this class, each command has its own callback...
Definition: m24sr_driver.h:238
Class representing a M24SR component.
Definition: m24sr_driver.h:232
The abstraction for a NFC EEPROM driver.
virtual void on_session_open(M24srDriver *nfc, M24srError_t status)
called when get_session completes
Definition: m24sr_driver.h:241
An I2C Master, used for communicating with I2C slave devices.
Definition: I2C.h:82
virtual void on_manage_i2c_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
called when manage_i2c_gpo completes
Definition: m24sr_driver.h:314
Callback< R(ArgTs...)> callback(R(*func)(ArgTs...)=nullptr) noexcept
Create a callback class with type inferred from the arguments.
Definition: Callback.h:678
virtual void on_updated_binary(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_written, uint16_t write_count)
called when update_binary completes
Definition: m24sr_driver.h:294
virtual void write_size(size_t count)
Definition: m24sr_driver.h:573
virtual void on_enable_write_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
called when oenable_write_password completes
Definition: m24sr_driver.h:388
uint16_t length
number of bytes in the data array
Definition: m24sr_driver.h:91
uint8_t SW1
Command Processing status.
Definition: m24sr_driver.h:133
virtual void on_selected_cc_file(M24srDriver *nfc, M24srError_t status)
called when select_cc_file completes
Definition: m24sr_driver.h:262
virtual void on_bytes_written(size_t count)=0
Completion of write operation.
virtual void on_verified(M24srDriver *nfc, M24srError_t status, PasswordType_t password_type, const uint8_t *pwd)
called when verify completes
Definition: m24sr_driver.h:305
virtual void on_enable_read_password(M24srDriver *nfc, M24srError_t status, const uint8_t *new_password)
called when enable_read_password completes
Definition: m24sr_driver.h:380
const uint8_t * data
Command parameters.
Definition: m24sr_driver.h:109
virtual void on_manage_rf_gpo(M24srDriver *nfc, M24srError_t status, NfcGpoState_t new_status)
called when manage_rf_gpo completes
Definition: m24sr_driver.h:322
uint8_t SW2
Command Processing qualification.
Definition: m24sr_driver.h:134
virtual void write_bytes(uint32_t address, const uint8_t *bytes, size_t count)
Definition: m24sr_driver.h:534
virtual void on_disable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when disable_permanent_state completes
Definition: m24sr_driver.h:364
A digital interrupt input, used to call a function on a rising or falling edge.
Definition: InterruptIn.h:65
virtual void on_enable_read_only(M24srDriver *nfc, M24srError_t status)
called when enable_read_only completes
Definition: m24sr_driver.h:417
virtual void on_selected_application(M24srDriver *nfc, M24srError_t status)
called when select_application completes
Definition: m24sr_driver.h:255
A digital output, used for setting the state of a pin.
Definition: DigitalOut.h:49
virtual void on_read_byte(M24srDriver *nfc, M24srError_t status, uint16_t offset, uint8_t *bytes_read, uint16_t read_count)
called when read_binary completes
Definition: m24sr_driver.h:283
virtual void on_disable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when disable_verification_requirement completes
Definition: m24sr_driver.h:348
uint16_t offset
offset parameter used in the read/write command
Definition: m24sr_driver.h:92
virtual void on_read_id(M24srDriver *nfc, M24srError_t status, uint8_t *id)
called when read_id completes
Definition: m24sr_driver.h:372
virtual void on_change_reference_data(M24srDriver *nfc, M24srError_t status, PasswordType_t type, const uint8_t *data)
called when change_reference_data completes
Definition: m24sr_driver.h:330
virtual void on_enable_verification_requirement(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when enable_verification_requirement completes
Definition: m24sr_driver.h:340
virtual void on_bytes_erased(size_t count)=0
Completion of erasing operation.
uint8_t * data
Data returned from the card.
Definition: m24sr_driver.h:132
APDU Command structure.
Definition: m24sr_driver.h:98
virtual void on_bytes_read(size_t count)=0
Completion of read operation.
A digital input, used for reading the state of a pin.
Definition: DigitalIn.h:54
virtual void start_session(bool force=true)
Definition: m24sr_driver.h:477
Definition: ATHandler.h:46
virtual void on_size_read(bool success, size_t size)=0
Completion of size retrieval operation.
virtual void on_disable_all_password(M24srDriver *nfc, M24srError_t status)
called when disable_all_password completes
Definition: m24sr_driver.h:410
virtual void read_bytes(uint32_t address, uint8_t *bytes, size_t count)
Definition: m24sr_driver.h:499
virtual void on_disable_read_only(M24srDriver *nfc, M24srError_t status)
called when disable_read_only completes
Definition: m24sr_driver.h:431
virtual void on_enable_permanent_state(M24srDriver *nfc, M24srError_t status, PasswordType_t type)
called when enable_permanent_state completes
Definition: m24sr_driver.h:356
User parameter used to invoke a command, it is used to provide the data back with the response...
Definition: m24sr_driver.h:89
uint8_t LE
Expected length of data to be returned.
Definition: m24sr_driver.h:110
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.