tinkerforge 2.1.15 → 2.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tinkerforge/brick_dc.rb +2 -2
  3. data/lib/tinkerforge/brick_imu.rb +2 -2
  4. data/lib/tinkerforge/brick_imu_v2.rb +2 -2
  5. data/lib/tinkerforge/brick_master.rb +2 -2
  6. data/lib/tinkerforge/brick_red.rb +2 -2
  7. data/lib/tinkerforge/brick_servo.rb +2 -2
  8. data/lib/tinkerforge/brick_silent_stepper.rb +2 -2
  9. data/lib/tinkerforge/brick_stepper.rb +2 -2
  10. data/lib/tinkerforge/bricklet_accelerometer.rb +2 -2
  11. data/lib/tinkerforge/bricklet_ambient_light.rb +2 -2
  12. data/lib/tinkerforge/bricklet_ambient_light_v2.rb +2 -2
  13. data/lib/tinkerforge/bricklet_analog_in.rb +2 -2
  14. data/lib/tinkerforge/bricklet_analog_in_v2.rb +2 -2
  15. data/lib/tinkerforge/bricklet_analog_in_v3.rb +319 -0
  16. data/lib/tinkerforge/bricklet_analog_out.rb +2 -2
  17. data/lib/tinkerforge/bricklet_analog_out_v2.rb +2 -2
  18. data/lib/tinkerforge/bricklet_barometer.rb +2 -2
  19. data/lib/tinkerforge/bricklet_can.rb +2 -2
  20. data/lib/tinkerforge/bricklet_co2.rb +2 -2
  21. data/lib/tinkerforge/bricklet_color.rb +2 -2
  22. data/lib/tinkerforge/bricklet_current12.rb +2 -2
  23. data/lib/tinkerforge/bricklet_current25.rb +2 -2
  24. data/lib/tinkerforge/bricklet_distance_ir.rb +2 -2
  25. data/lib/tinkerforge/bricklet_distance_us.rb +2 -2
  26. data/lib/tinkerforge/bricklet_dmx.rb +3 -3
  27. data/lib/tinkerforge/bricklet_dual_button.rb +2 -2
  28. data/lib/tinkerforge/bricklet_dual_relay.rb +2 -2
  29. data/lib/tinkerforge/bricklet_dust_detector.rb +2 -2
  30. data/lib/tinkerforge/bricklet_gps.rb +2 -2
  31. data/lib/tinkerforge/bricklet_gps_v2.rb +2 -2
  32. data/lib/tinkerforge/bricklet_hall_effect.rb +2 -2
  33. data/lib/tinkerforge/bricklet_humidity.rb +2 -2
  34. data/lib/tinkerforge/bricklet_humidity_v2.rb +2 -2
  35. data/lib/tinkerforge/bricklet_industrial_analog_out.rb +2 -2
  36. data/lib/tinkerforge/bricklet_industrial_digital_in_4.rb +2 -2
  37. data/lib/tinkerforge/bricklet_industrial_digital_out_4.rb +2 -2
  38. data/lib/tinkerforge/bricklet_industrial_dual_0_20ma.rb +2 -2
  39. data/lib/tinkerforge/bricklet_industrial_dual_analog_in.rb +2 -2
  40. data/lib/tinkerforge/bricklet_industrial_quad_relay.rb +2 -2
  41. data/lib/tinkerforge/bricklet_io16.rb +2 -2
  42. data/lib/tinkerforge/bricklet_io4.rb +2 -2
  43. data/lib/tinkerforge/bricklet_joystick.rb +2 -2
  44. data/lib/tinkerforge/bricklet_laser_range_finder.rb +2 -2
  45. data/lib/tinkerforge/bricklet_lcd_16x2.rb +2 -2
  46. data/lib/tinkerforge/bricklet_lcd_20x4.rb +2 -2
  47. data/lib/tinkerforge/bricklet_led_strip.rb +2 -2
  48. data/lib/tinkerforge/bricklet_line.rb +2 -2
  49. data/lib/tinkerforge/bricklet_linear_poti.rb +2 -2
  50. data/lib/tinkerforge/bricklet_load_cell.rb +2 -2
  51. data/lib/tinkerforge/bricklet_moisture.rb +2 -2
  52. data/lib/tinkerforge/bricklet_motion_detector.rb +2 -2
  53. data/lib/tinkerforge/bricklet_motion_detector_v2.rb +261 -0
  54. data/lib/tinkerforge/bricklet_motorized_linear_poti.rb +2 -2
  55. data/lib/tinkerforge/bricklet_multi_touch.rb +2 -2
  56. data/lib/tinkerforge/bricklet_nfc.rb +998 -0
  57. data/lib/tinkerforge/bricklet_nfc_rfid.rb +5 -5
  58. data/lib/tinkerforge/bricklet_oled_128x64.rb +2 -2
  59. data/lib/tinkerforge/bricklet_oled_64x48.rb +2 -2
  60. data/lib/tinkerforge/bricklet_outdoor_weather.rb +390 -0
  61. data/lib/tinkerforge/bricklet_piezo_buzzer.rb +2 -2
  62. data/lib/tinkerforge/bricklet_piezo_speaker.rb +2 -2
  63. data/lib/tinkerforge/bricklet_ptc.rb +2 -2
  64. data/lib/tinkerforge/bricklet_real_time_clock.rb +2 -2
  65. data/lib/tinkerforge/bricklet_remote_switch.rb +3 -3
  66. data/lib/tinkerforge/bricklet_remote_switch_v2.rb +403 -0
  67. data/lib/tinkerforge/bricklet_rgb_led.rb +2 -2
  68. data/lib/tinkerforge/bricklet_rgb_led_button.rb +3 -3
  69. data/lib/tinkerforge/bricklet_rgb_led_matrix.rb +2 -2
  70. data/lib/tinkerforge/bricklet_rotary_encoder.rb +2 -2
  71. data/lib/tinkerforge/bricklet_rotary_encoder_v2.rb +284 -0
  72. data/lib/tinkerforge/bricklet_rotary_poti.rb +2 -2
  73. data/lib/tinkerforge/bricklet_rs232.rb +2 -2
  74. data/lib/tinkerforge/bricklet_rs485.rb +2 -2
  75. data/lib/tinkerforge/bricklet_segment_display_4x7.rb +2 -2
  76. data/lib/tinkerforge/bricklet_solid_state_relay.rb +2 -2
  77. data/lib/tinkerforge/bricklet_solid_state_relay_v2.rb +247 -0
  78. data/lib/tinkerforge/bricklet_sound_intensity.rb +2 -2
  79. data/lib/tinkerforge/bricklet_temperature.rb +2 -2
  80. data/lib/tinkerforge/bricklet_temperature_ir.rb +2 -2
  81. data/lib/tinkerforge/bricklet_temperature_ir_v2.rb +369 -0
  82. data/lib/tinkerforge/bricklet_thermal_imaging.rb +5 -2
  83. data/lib/tinkerforge/bricklet_thermocouple.rb +2 -2
  84. data/lib/tinkerforge/bricklet_tilt.rb +2 -2
  85. data/lib/tinkerforge/bricklet_uv_light.rb +2 -2
  86. data/lib/tinkerforge/bricklet_voltage.rb +2 -2
  87. data/lib/tinkerforge/bricklet_voltage_current.rb +2 -2
  88. data/lib/tinkerforge/version.rb +1 -1
  89. metadata +11 -3
@@ -0,0 +1,261 @@
1
+ # -*- ruby encoding: utf-8 -*-
2
+ #############################################################
3
+ # This file was automatically generated on 2018-02-28. #
4
+ # #
5
+ # Ruby Bindings Version 2.1.16 #
6
+ # #
7
+ # If you have a bugfix for this file and want to commit it, #
8
+ # please fix the bug in the generator. You can find a link #
9
+ # to the generators git repository on tinkerforge.com #
10
+ #############################################################
11
+
12
+ module Tinkerforge
13
+ # Passive infrared (PIR) motion sensor, 12m range
14
+ class BrickletMotionDetectorV2 < Device
15
+ DEVICE_IDENTIFIER = 292 # :nodoc:
16
+ DEVICE_DISPLAY_NAME = 'Motion Detector Bricklet 2.0' # :nodoc:
17
+
18
+ # This callback is called after a motion was detected.
19
+ CALLBACK_MOTION_DETECTED = 6
20
+
21
+ # This callback is called when the detection cycle ended. When this
22
+ # callback is called, a new motion can be detected again after approximately 2
23
+ # seconds.
24
+ CALLBACK_DETECTION_CYCLE_ENDED = 7
25
+
26
+ FUNCTION_GET_MOTION_DETECTED = 1 # :nodoc:
27
+ FUNCTION_SET_SENSITIVITY = 2 # :nodoc:
28
+ FUNCTION_GET_SENSITIVITY = 3 # :nodoc:
29
+ FUNCTION_SET_INDICATOR = 4 # :nodoc:
30
+ FUNCTION_GET_INDICATOR = 5 # :nodoc:
31
+ FUNCTION_GET_SPITFP_ERROR_COUNT = 234 # :nodoc:
32
+ FUNCTION_SET_BOOTLOADER_MODE = 235 # :nodoc:
33
+ FUNCTION_GET_BOOTLOADER_MODE = 236 # :nodoc:
34
+ FUNCTION_SET_WRITE_FIRMWARE_POINTER = 237 # :nodoc:
35
+ FUNCTION_WRITE_FIRMWARE = 238 # :nodoc:
36
+ FUNCTION_SET_STATUS_LED_CONFIG = 239 # :nodoc:
37
+ FUNCTION_GET_STATUS_LED_CONFIG = 240 # :nodoc:
38
+ FUNCTION_GET_CHIP_TEMPERATURE = 242 # :nodoc:
39
+ FUNCTION_RESET = 243 # :nodoc:
40
+ FUNCTION_WRITE_UID = 248 # :nodoc:
41
+ FUNCTION_READ_UID = 249 # :nodoc:
42
+ FUNCTION_GET_IDENTITY = 255 # :nodoc:
43
+
44
+ MOTION_NOT_DETECTED = 0 # :nodoc:
45
+ MOTION_DETECTED = 1 # :nodoc:
46
+ BOOTLOADER_MODE_BOOTLOADER = 0 # :nodoc:
47
+ BOOTLOADER_MODE_FIRMWARE = 1 # :nodoc:
48
+ BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT = 2 # :nodoc:
49
+ BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT = 3 # :nodoc:
50
+ BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT = 4 # :nodoc:
51
+ BOOTLOADER_STATUS_OK = 0 # :nodoc:
52
+ BOOTLOADER_STATUS_INVALID_MODE = 1 # :nodoc:
53
+ BOOTLOADER_STATUS_NO_CHANGE = 2 # :nodoc:
54
+ BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT = 3 # :nodoc:
55
+ BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT = 4 # :nodoc:
56
+ BOOTLOADER_STATUS_CRC_MISMATCH = 5 # :nodoc:
57
+ STATUS_LED_CONFIG_OFF = 0 # :nodoc:
58
+ STATUS_LED_CONFIG_ON = 1 # :nodoc:
59
+ STATUS_LED_CONFIG_SHOW_HEARTBEAT = 2 # :nodoc:
60
+ STATUS_LED_CONFIG_SHOW_STATUS = 3 # :nodoc:
61
+
62
+ # Creates an object with the unique device ID <tt>uid</tt> and adds it to
63
+ # the IP Connection <tt>ipcon</tt>.
64
+ def initialize(uid, ipcon)
65
+ super uid, ipcon
66
+
67
+ @api_version = [2, 0, 0]
68
+
69
+ @response_expected[FUNCTION_GET_MOTION_DETECTED] = RESPONSE_EXPECTED_ALWAYS_TRUE
70
+ @response_expected[FUNCTION_SET_SENSITIVITY] = RESPONSE_EXPECTED_FALSE
71
+ @response_expected[FUNCTION_GET_SENSITIVITY] = RESPONSE_EXPECTED_ALWAYS_TRUE
72
+ @response_expected[FUNCTION_SET_INDICATOR] = RESPONSE_EXPECTED_FALSE
73
+ @response_expected[FUNCTION_GET_INDICATOR] = RESPONSE_EXPECTED_ALWAYS_TRUE
74
+ @response_expected[FUNCTION_GET_SPITFP_ERROR_COUNT] = RESPONSE_EXPECTED_ALWAYS_TRUE
75
+ @response_expected[FUNCTION_SET_BOOTLOADER_MODE] = RESPONSE_EXPECTED_ALWAYS_TRUE
76
+ @response_expected[FUNCTION_GET_BOOTLOADER_MODE] = RESPONSE_EXPECTED_ALWAYS_TRUE
77
+ @response_expected[FUNCTION_SET_WRITE_FIRMWARE_POINTER] = RESPONSE_EXPECTED_FALSE
78
+ @response_expected[FUNCTION_WRITE_FIRMWARE] = RESPONSE_EXPECTED_ALWAYS_TRUE
79
+ @response_expected[FUNCTION_SET_STATUS_LED_CONFIG] = RESPONSE_EXPECTED_FALSE
80
+ @response_expected[FUNCTION_GET_STATUS_LED_CONFIG] = RESPONSE_EXPECTED_ALWAYS_TRUE
81
+ @response_expected[FUNCTION_GET_CHIP_TEMPERATURE] = RESPONSE_EXPECTED_ALWAYS_TRUE
82
+ @response_expected[FUNCTION_RESET] = RESPONSE_EXPECTED_FALSE
83
+ @response_expected[FUNCTION_WRITE_UID] = RESPONSE_EXPECTED_FALSE
84
+ @response_expected[FUNCTION_READ_UID] = RESPONSE_EXPECTED_ALWAYS_TRUE
85
+ @response_expected[FUNCTION_GET_IDENTITY] = RESPONSE_EXPECTED_ALWAYS_TRUE
86
+
87
+ @callback_formats[CALLBACK_MOTION_DETECTED] = ''
88
+ @callback_formats[CALLBACK_DETECTION_CYCLE_ENDED] = ''
89
+
90
+ end
91
+
92
+ # Returns 1 if a motion was detected. How long this returns 1 after a motion
93
+ # was detected can be adjusted with one of the small potentiometers on the
94
+ # Motion Detector Bricklet, see :ref:`here
95
+ # <motion_detector_bricklet_sensitivity_delay_block_time>`.
96
+ #
97
+ # There is also a blue LED on the Bricklet that is on as long as the Bricklet is
98
+ # in the "motion detected" state.
99
+ def get_motion_detected
100
+ send_request FUNCTION_GET_MOTION_DETECTED, [], '', 1, 'C'
101
+ end
102
+
103
+ # Sets the sensitivity of the PIR sensor. The range is 0-100. At full
104
+ # sensitivity (100), the Bricklet can detect motion in a range of approximately 12m.
105
+ #
106
+ # The actual range depends on many things in the environment (e.g. reflections) and the
107
+ # size of the object to be detected. While a big person might be detected in a range
108
+ # of 10m a cat may only be detected at 2m distance with the same setting.
109
+ #
110
+ # So you will have to find a good sensitivity for your application by trial and error.
111
+ #
112
+ # The default value is 50.
113
+ def set_sensitivity(sensitivity)
114
+ send_request FUNCTION_SET_SENSITIVITY, [sensitivity], 'C', 0, ''
115
+ end
116
+
117
+ # Returns the sensitivity as set by BrickletMotionDetectorV2#set_sensitivity.
118
+ def get_sensitivity
119
+ send_request FUNCTION_GET_SENSITIVITY, [], '', 1, 'C'
120
+ end
121
+
122
+ # Sets the blue backlight of the fresnel lens. The backlight consists of
123
+ # three LEDs. The brightness of each LED can be controlled with a 8-bit value
124
+ # (0-255). A value of 0 turns the LED off and a value of 255 turns the LED
125
+ # to full brightness.
126
+ #
127
+ # The default value is 0, 0, 0.
128
+ def set_indicator(top_left, top_right, bottom)
129
+ send_request FUNCTION_SET_INDICATOR, [top_left, top_right, bottom], 'C C C', 0, ''
130
+ end
131
+
132
+ # Returns the indicator configuration as set by BrickletMotionDetectorV2#set_indicator.
133
+ def get_indicator
134
+ send_request FUNCTION_GET_INDICATOR, [], '', 3, 'C C C'
135
+ end
136
+
137
+ # Returns the error count for the communication between Brick and Bricklet.
138
+ #
139
+ # The errors are divided into
140
+ #
141
+ # * ack checksum errors,
142
+ # * message checksum errors,
143
+ # * frameing errors and
144
+ # * overflow errors.
145
+ #
146
+ # The errors counts are for errors that occur on the Bricklet side. All
147
+ # Bricks have a similar function that returns the errors on the Brick side.
148
+ def get_spitfp_error_count
149
+ send_request FUNCTION_GET_SPITFP_ERROR_COUNT, [], '', 16, 'L L L L'
150
+ end
151
+
152
+ # Sets the bootloader mode and returns the status after the requested
153
+ # mode change was instigated.
154
+ #
155
+ # You can change from bootloader mode to firmware mode and vice versa. A change
156
+ # from bootloader mode to firmware mode will only take place if the entry function,
157
+ # device identifier und crc are present and correct.
158
+ #
159
+ # This function is used by Brick Viewer during flashing. It should not be
160
+ # necessary to call it in a normal user program.
161
+ def set_bootloader_mode(mode)
162
+ send_request FUNCTION_SET_BOOTLOADER_MODE, [mode], 'C', 1, 'C'
163
+ end
164
+
165
+ # Returns the current bootloader mode, see BrickletMotionDetectorV2#set_bootloader_mode.
166
+ def get_bootloader_mode
167
+ send_request FUNCTION_GET_BOOTLOADER_MODE, [], '', 1, 'C'
168
+ end
169
+
170
+ # Sets the firmware pointer for BrickletMotionDetectorV2#write_firmware. The pointer has
171
+ # to be increased by chunks of size 64. The data is written to flash
172
+ # every 4 chunks (which equals to one page of size 256).
173
+ #
174
+ # This function is used by Brick Viewer during flashing. It should not be
175
+ # necessary to call it in a normal user program.
176
+ def set_write_firmware_pointer(pointer)
177
+ send_request FUNCTION_SET_WRITE_FIRMWARE_POINTER, [pointer], 'L', 0, ''
178
+ end
179
+
180
+ # Writes 64 Bytes of firmware at the position as written by
181
+ # BrickletMotionDetectorV2#set_write_firmware_pointer before. The firmware is written
182
+ # to flash every 4 chunks.
183
+ #
184
+ # You can only write firmware in bootloader mode.
185
+ #
186
+ # This function is used by Brick Viewer during flashing. It should not be
187
+ # necessary to call it in a normal user program.
188
+ def write_firmware(data)
189
+ send_request FUNCTION_WRITE_FIRMWARE, [data], 'C64', 1, 'C'
190
+ end
191
+
192
+ # Sets the status LED configuration. By default the LED shows
193
+ # communication traffic between Brick and Bricklet, it flickers once
194
+ # for every 10 received data packets.
195
+ #
196
+ # You can also turn the LED permanently on/off or show a heartbeat.
197
+ #
198
+ # If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
199
+ def set_status_led_config(config)
200
+ send_request FUNCTION_SET_STATUS_LED_CONFIG, [config], 'C', 0, ''
201
+ end
202
+
203
+ # Returns the configuration as set by BrickletMotionDetectorV2#set_status_led_config
204
+ def get_status_led_config
205
+ send_request FUNCTION_GET_STATUS_LED_CONFIG, [], '', 1, 'C'
206
+ end
207
+
208
+ # Returns the temperature in °C as measured inside the microcontroller. The
209
+ # value returned is not the ambient temperature!
210
+ #
211
+ # The temperature is only proportional to the real temperature and it has bad
212
+ # accuracy. Practically it is only useful as an indicator for
213
+ # temperature changes.
214
+ def get_chip_temperature
215
+ send_request FUNCTION_GET_CHIP_TEMPERATURE, [], '', 2, 's'
216
+ end
217
+
218
+ # Calling this function will reset the Bricklet. All configurations
219
+ # will be lost.
220
+ #
221
+ # After a reset you have to create new device objects,
222
+ # calling functions on the existing ones will result in
223
+ # undefined behavior!
224
+ def reset
225
+ send_request FUNCTION_RESET, [], '', 0, ''
226
+ end
227
+
228
+ # Writes a new UID into flash. If you want to set a new UID
229
+ # you have to decode the Base58 encoded UID string into an
230
+ # integer first.
231
+ #
232
+ # We recommend that you use Brick Viewer to change the UID.
233
+ def write_uid(uid)
234
+ send_request FUNCTION_WRITE_UID, [uid], 'L', 0, ''
235
+ end
236
+
237
+ # Returns the current UID as an integer. Encode as
238
+ # Base58 to get the usual string version.
239
+ def read_uid
240
+ send_request FUNCTION_READ_UID, [], '', 4, 'L'
241
+ end
242
+
243
+ # Returns the UID, the UID where the Bricklet is connected to,
244
+ # the position, the hardware and firmware version as well as the
245
+ # device identifier.
246
+ #
247
+ # The position can be 'a', 'b', 'c' or 'd'.
248
+ #
249
+ # The device identifier numbers can be found :ref:`here <device_identifier>`.
250
+ # |device_identifier_constant|
251
+ def get_identity
252
+ send_request FUNCTION_GET_IDENTITY, [], '', 25, 'Z8 Z8 k C3 C3 S'
253
+ end
254
+
255
+ # Registers a callback with ID <tt>id</tt> to the block <tt>block</tt>.
256
+ def register_callback(id, &block)
257
+ callback = block
258
+ @registered_callbacks[id] = callback
259
+ end
260
+ end
261
+ end
@@ -1,8 +1,8 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
  #############################################################
3
- # This file was automatically generated on 2017-11-20. #
3
+ # This file was automatically generated on 2018-02-28. #
4
4
  # #
5
- # Ruby Bindings Version 2.1.15 #
5
+ # Ruby Bindings Version 2.1.16 #
6
6
  # #
7
7
  # If you have a bugfix for this file and want to commit it, #
8
8
  # please fix the bug in the generator. You can find a link #
@@ -1,8 +1,8 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
  #############################################################
3
- # This file was automatically generated on 2017-11-20. #
3
+ # This file was automatically generated on 2018-02-28. #
4
4
  # #
5
- # Ruby Bindings Version 2.1.15 #
5
+ # Ruby Bindings Version 2.1.16 #
6
6
  # #
7
7
  # If you have a bugfix for this file and want to commit it, #
8
8
  # please fix the bug in the generator. You can find a link #
@@ -0,0 +1,998 @@
1
+ # -*- ruby encoding: utf-8 -*-
2
+ #############################################################
3
+ # This file was automatically generated on 2018-02-28. #
4
+ # #
5
+ # Ruby Bindings Version 2.1.16 #
6
+ # #
7
+ # If you have a bugfix for this file and want to commit it, #
8
+ # please fix the bug in the generator. You can find a link #
9
+ # to the generators git repository on tinkerforge.com #
10
+ #############################################################
11
+
12
+ module Tinkerforge
13
+ # NFC tag read/write, NFC P2P and Card Emulation
14
+ class BrickletNFC < Device
15
+ DEVICE_IDENTIFIER = 286 # :nodoc:
16
+ DEVICE_DISPLAY_NAME = 'NFC Bricklet' # :nodoc:
17
+
18
+ # This callback is called if the reader state of the NFC Bricklet changes.
19
+ # See BrickletNFC#reader_get_state for more information about the possible states.
20
+ CALLBACK_READER_STATE_CHANGED = 13
21
+
22
+ # This callback is called if the cardemu state of the NFC Bricklet changes.
23
+ # See BrickletNFC#cardemu_get_state for more information about the possible states.
24
+ CALLBACK_CARDEMU_STATE_CHANGED = 18
25
+
26
+ # This callback is called if the P2P state of the NFC Bricklet changes.
27
+ # See BrickletNFC#p2p_get_state for more information about the possible states.
28
+ CALLBACK_P2P_STATE_CHANGED = 24
29
+
30
+ FUNCTION_SET_MODE = 1 # :nodoc:
31
+ FUNCTION_GET_MODE = 2 # :nodoc:
32
+ FUNCTION_READER_REQUEST_TAG_ID = 3 # :nodoc:
33
+ FUNCTION_READER_GET_TAG_ID_LOW_LEVEL = 4 # :nodoc:
34
+ FUNCTION_READER_GET_STATE = 5 # :nodoc:
35
+ FUNCTION_READER_WRITE_NDEF_LOW_LEVEL = 6 # :nodoc:
36
+ FUNCTION_READER_REQUEST_NDEF = 7 # :nodoc:
37
+ FUNCTION_READER_READ_NDEF_LOW_LEVEL = 8 # :nodoc:
38
+ FUNCTION_READER_AUTHENTICATE_MIFARE_CLASSIC_PAGE = 9 # :nodoc:
39
+ FUNCTION_READER_WRITE_PAGE_LOW_LEVEL = 10 # :nodoc:
40
+ FUNCTION_READER_REQUEST_PAGE = 11 # :nodoc:
41
+ FUNCTION_READER_READ_PAGE_LOW_LEVEL = 12 # :nodoc:
42
+ FUNCTION_CARDEMU_GET_STATE = 14 # :nodoc:
43
+ FUNCTION_CARDEMU_START_DISCOVERY = 15 # :nodoc:
44
+ FUNCTION_CARDEMU_WRITE_NDEF_LOW_LEVEL = 16 # :nodoc:
45
+ FUNCTION_CARDEMU_START_TRANSFER = 17 # :nodoc:
46
+ FUNCTION_P2P_GET_STATE = 19 # :nodoc:
47
+ FUNCTION_P2P_START_DISCOVERY = 20 # :nodoc:
48
+ FUNCTION_P2P_WRITE_NDEF_LOW_LEVEL = 21 # :nodoc:
49
+ FUNCTION_P2P_START_TRANSFER = 22 # :nodoc:
50
+ FUNCTION_P2P_READ_NDEF_LOW_LEVEL = 23 # :nodoc:
51
+ FUNCTION_SET_DETECTION_LED_CONFIG = 25 # :nodoc:
52
+ FUNCTION_GET_DETECTION_LED_CONFIG = 26 # :nodoc:
53
+ FUNCTION_GET_SPITFP_ERROR_COUNT = 234 # :nodoc:
54
+ FUNCTION_SET_BOOTLOADER_MODE = 235 # :nodoc:
55
+ FUNCTION_GET_BOOTLOADER_MODE = 236 # :nodoc:
56
+ FUNCTION_SET_WRITE_FIRMWARE_POINTER = 237 # :nodoc:
57
+ FUNCTION_WRITE_FIRMWARE = 238 # :nodoc:
58
+ FUNCTION_SET_STATUS_LED_CONFIG = 239 # :nodoc:
59
+ FUNCTION_GET_STATUS_LED_CONFIG = 240 # :nodoc:
60
+ FUNCTION_GET_CHIP_TEMPERATURE = 242 # :nodoc:
61
+ FUNCTION_RESET = 243 # :nodoc:
62
+ FUNCTION_WRITE_UID = 248 # :nodoc:
63
+ FUNCTION_READ_UID = 249 # :nodoc:
64
+ FUNCTION_GET_IDENTITY = 255 # :nodoc:
65
+
66
+ MODE_OFF = 0 # :nodoc:
67
+ MODE_CARDEMU = 1 # :nodoc:
68
+ MODE_P2P = 2 # :nodoc:
69
+ MODE_READER = 3 # :nodoc:
70
+ TAG_TYPE_MIFARE_CLASSIC = 0 # :nodoc:
71
+ TAG_TYPE_TYPE1 = 1 # :nodoc:
72
+ TAG_TYPE_TYPE2 = 2 # :nodoc:
73
+ TAG_TYPE_TYPE3 = 3 # :nodoc:
74
+ TAG_TYPE_TYPE4 = 4 # :nodoc:
75
+ READER_STATE_INITIALIZATION = 0 # :nodoc:
76
+ READER_STATE_IDLE = 128 # :nodoc:
77
+ READER_STATE_ERROR = 192 # :nodoc:
78
+ READER_STATE_REQUEST_TAG_ID = 2 # :nodoc:
79
+ READER_STATE_REQUEST_TAG_ID_READY = 130 # :nodoc:
80
+ READER_STATE_REQUEST_TAG_ID_ERROR = 194 # :nodoc:
81
+ READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE = 3 # :nodoc:
82
+ READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE_READY = 131 # :nodoc:
83
+ READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE_ERROR = 195 # :nodoc:
84
+ READER_STATE_WRITE_PAGE = 4 # :nodoc:
85
+ READER_STATE_WRITE_PAGE_READY = 132 # :nodoc:
86
+ READER_STATE_WRITE_PAGE_ERROR = 196 # :nodoc:
87
+ READER_STATE_REQUEST_PAGE = 5 # :nodoc:
88
+ READER_STATE_REQUEST_PAGE_READY = 133 # :nodoc:
89
+ READER_STATE_REQUEST_PAGE_ERROR = 197 # :nodoc:
90
+ READER_STATE_WRITE_NDEF = 6 # :nodoc:
91
+ READER_STATE_WRITE_NDEF_READY = 134 # :nodoc:
92
+ READER_STATE_WRITE_NDEF_ERROR = 198 # :nodoc:
93
+ READER_STATE_REQUEST_NDEF = 7 # :nodoc:
94
+ READER_STATE_REQUEST_NDEF_READY = 135 # :nodoc:
95
+ READER_STATE_REQUEST_NDEF_ERROR = 199 # :nodoc:
96
+ KEY_A = 0 # :nodoc:
97
+ KEY_B = 1 # :nodoc:
98
+ READER_WRITE_TYPE4_CAPABILITY_CONTAINER = 3 # :nodoc:
99
+ READER_WRITE_TYPE4_NDEF = 4 # :nodoc:
100
+ READER_REQUEST_TYPE4_CAPABILITY_CONTAINER = 3 # :nodoc:
101
+ READER_REQUEST_TYPE4_NDEF = 4 # :nodoc:
102
+ CARDEMU_STATE_INITIALIZATION = 0 # :nodoc:
103
+ CARDEMU_STATE_IDLE = 128 # :nodoc:
104
+ CARDEMU_STATE_ERROR = 192 # :nodoc:
105
+ CARDEMU_STATE_DISCOVER = 2 # :nodoc:
106
+ CARDEMU_STATE_DISCOVER_READY = 130 # :nodoc:
107
+ CARDEMU_STATE_DISCOVER_ERROR = 194 # :nodoc:
108
+ CARDEMU_STATE_TRANSFER_NDEF = 3 # :nodoc:
109
+ CARDEMU_STATE_TRANSFER_NDEF_READY = 131 # :nodoc:
110
+ CARDEMU_STATE_TRANSFER_NDEF_ERROR = 195 # :nodoc:
111
+ CARDEMU_TRANSFER_ABORT = 0 # :nodoc:
112
+ CARDEMU_TRANSFER_WRITE = 1 # :nodoc:
113
+ P2P_STATE_INITIALIZATION = 0 # :nodoc:
114
+ P2P_STATE_IDLE = 128 # :nodoc:
115
+ P2P_STATE_ERROR = 192 # :nodoc:
116
+ P2P_STATE_DISCOVER = 2 # :nodoc:
117
+ P2P_STATE_DISCOVER_READY = 130 # :nodoc:
118
+ P2P_STATE_DISCOVER_ERROR = 194 # :nodoc:
119
+ P2P_STATE_TRANSFER_NDEF = 3 # :nodoc:
120
+ P2P_STATE_TRANSFER_NDEF_READY = 131 # :nodoc:
121
+ P2P_STATE_TRANSFER_NDEF_ERROR = 195 # :nodoc:
122
+ P2P_TRANSFER_ABORT = 0 # :nodoc:
123
+ P2P_TRANSFER_WRITE = 1 # :nodoc:
124
+ P2P_TRANSFER_READ = 2 # :nodoc:
125
+ DETECTION_LED_CONFIG_OFF = 0 # :nodoc:
126
+ DETECTION_LED_CONFIG_ON = 1 # :nodoc:
127
+ DETECTION_LED_CONFIG_SHOW_HEARTBEAT = 2 # :nodoc:
128
+ DETECTION_LED_CONFIG_SHOW_DETECTION = 3 # :nodoc:
129
+ BOOTLOADER_MODE_BOOTLOADER = 0 # :nodoc:
130
+ BOOTLOADER_MODE_FIRMWARE = 1 # :nodoc:
131
+ BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT = 2 # :nodoc:
132
+ BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT = 3 # :nodoc:
133
+ BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT = 4 # :nodoc:
134
+ BOOTLOADER_STATUS_OK = 0 # :nodoc:
135
+ BOOTLOADER_STATUS_INVALID_MODE = 1 # :nodoc:
136
+ BOOTLOADER_STATUS_NO_CHANGE = 2 # :nodoc:
137
+ BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT = 3 # :nodoc:
138
+ BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT = 4 # :nodoc:
139
+ BOOTLOADER_STATUS_CRC_MISMATCH = 5 # :nodoc:
140
+ STATUS_LED_CONFIG_OFF = 0 # :nodoc:
141
+ STATUS_LED_CONFIG_ON = 1 # :nodoc:
142
+ STATUS_LED_CONFIG_SHOW_HEARTBEAT = 2 # :nodoc:
143
+ STATUS_LED_CONFIG_SHOW_STATUS = 3 # :nodoc:
144
+
145
+ # Creates an object with the unique device ID <tt>uid</tt> and adds it to
146
+ # the IP Connection <tt>ipcon</tt>.
147
+ def initialize(uid, ipcon)
148
+ super uid, ipcon
149
+
150
+ @api_version = [2, 0, 0]
151
+
152
+ @response_expected[FUNCTION_SET_MODE] = RESPONSE_EXPECTED_FALSE
153
+ @response_expected[FUNCTION_GET_MODE] = RESPONSE_EXPECTED_ALWAYS_TRUE
154
+ @response_expected[FUNCTION_READER_REQUEST_TAG_ID] = RESPONSE_EXPECTED_FALSE
155
+ @response_expected[FUNCTION_READER_GET_TAG_ID_LOW_LEVEL] = RESPONSE_EXPECTED_ALWAYS_TRUE
156
+ @response_expected[FUNCTION_READER_GET_STATE] = RESPONSE_EXPECTED_ALWAYS_TRUE
157
+ @response_expected[FUNCTION_READER_WRITE_NDEF_LOW_LEVEL] = RESPONSE_EXPECTED_TRUE
158
+ @response_expected[FUNCTION_READER_REQUEST_NDEF] = RESPONSE_EXPECTED_FALSE
159
+ @response_expected[FUNCTION_READER_READ_NDEF_LOW_LEVEL] = RESPONSE_EXPECTED_ALWAYS_TRUE
160
+ @response_expected[FUNCTION_READER_AUTHENTICATE_MIFARE_CLASSIC_PAGE] = RESPONSE_EXPECTED_FALSE
161
+ @response_expected[FUNCTION_READER_WRITE_PAGE_LOW_LEVEL] = RESPONSE_EXPECTED_TRUE
162
+ @response_expected[FUNCTION_READER_REQUEST_PAGE] = RESPONSE_EXPECTED_FALSE
163
+ @response_expected[FUNCTION_READER_READ_PAGE_LOW_LEVEL] = RESPONSE_EXPECTED_ALWAYS_TRUE
164
+ @response_expected[FUNCTION_CARDEMU_GET_STATE] = RESPONSE_EXPECTED_ALWAYS_TRUE
165
+ @response_expected[FUNCTION_CARDEMU_START_DISCOVERY] = RESPONSE_EXPECTED_FALSE
166
+ @response_expected[FUNCTION_CARDEMU_WRITE_NDEF_LOW_LEVEL] = RESPONSE_EXPECTED_TRUE
167
+ @response_expected[FUNCTION_CARDEMU_START_TRANSFER] = RESPONSE_EXPECTED_FALSE
168
+ @response_expected[FUNCTION_P2P_GET_STATE] = RESPONSE_EXPECTED_ALWAYS_TRUE
169
+ @response_expected[FUNCTION_P2P_START_DISCOVERY] = RESPONSE_EXPECTED_FALSE
170
+ @response_expected[FUNCTION_P2P_WRITE_NDEF_LOW_LEVEL] = RESPONSE_EXPECTED_TRUE
171
+ @response_expected[FUNCTION_P2P_START_TRANSFER] = RESPONSE_EXPECTED_FALSE
172
+ @response_expected[FUNCTION_P2P_READ_NDEF_LOW_LEVEL] = RESPONSE_EXPECTED_ALWAYS_TRUE
173
+ @response_expected[FUNCTION_SET_DETECTION_LED_CONFIG] = RESPONSE_EXPECTED_FALSE
174
+ @response_expected[FUNCTION_GET_DETECTION_LED_CONFIG] = RESPONSE_EXPECTED_ALWAYS_TRUE
175
+ @response_expected[FUNCTION_GET_SPITFP_ERROR_COUNT] = RESPONSE_EXPECTED_ALWAYS_TRUE
176
+ @response_expected[FUNCTION_SET_BOOTLOADER_MODE] = RESPONSE_EXPECTED_ALWAYS_TRUE
177
+ @response_expected[FUNCTION_GET_BOOTLOADER_MODE] = RESPONSE_EXPECTED_ALWAYS_TRUE
178
+ @response_expected[FUNCTION_SET_WRITE_FIRMWARE_POINTER] = RESPONSE_EXPECTED_FALSE
179
+ @response_expected[FUNCTION_WRITE_FIRMWARE] = RESPONSE_EXPECTED_ALWAYS_TRUE
180
+ @response_expected[FUNCTION_SET_STATUS_LED_CONFIG] = RESPONSE_EXPECTED_FALSE
181
+ @response_expected[FUNCTION_GET_STATUS_LED_CONFIG] = RESPONSE_EXPECTED_ALWAYS_TRUE
182
+ @response_expected[FUNCTION_GET_CHIP_TEMPERATURE] = RESPONSE_EXPECTED_ALWAYS_TRUE
183
+ @response_expected[FUNCTION_RESET] = RESPONSE_EXPECTED_FALSE
184
+ @response_expected[FUNCTION_WRITE_UID] = RESPONSE_EXPECTED_FALSE
185
+ @response_expected[FUNCTION_READ_UID] = RESPONSE_EXPECTED_ALWAYS_TRUE
186
+ @response_expected[FUNCTION_GET_IDENTITY] = RESPONSE_EXPECTED_ALWAYS_TRUE
187
+
188
+ @callback_formats[CALLBACK_READER_STATE_CHANGED] = 'C ?'
189
+ @callback_formats[CALLBACK_CARDEMU_STATE_CHANGED] = 'C ?'
190
+ @callback_formats[CALLBACK_P2P_STATE_CHANGED] = 'C ?'
191
+
192
+ end
193
+
194
+ # Sets the mode. The NFC Bricklet supports four modes:
195
+ #
196
+ # * Off
197
+ # * Card Emulation (Cardemu): Emulates a tag for other readers
198
+ # * Peer to Peer (P2P): Exchange data with other readers
199
+ # * Reader: Reads and writes tags
200
+ #
201
+ # If you change a mode, the Bricklet will reconfigure the hardware for this mode.
202
+ # Therefore, you can only use functions corresponding to the current mode. For
203
+ # example, in Reader mode you can only use Reader functions.
204
+ #
205
+ # The default mode is "off".
206
+ def set_mode(mode)
207
+ send_request FUNCTION_SET_MODE, [mode], 'C', 0, ''
208
+ end
209
+
210
+ # Returns the mode as set by BrickletNFC#set_mode.
211
+ def get_mode
212
+ send_request FUNCTION_GET_MODE, [], '', 1, 'C'
213
+ end
214
+
215
+ # To read or write a tag that is in proximity of the NFC Bricklet you
216
+ # first have to call this function with the expected tag type as parameter.
217
+ # It is no problem if you don't know the tag type. You can cycle through
218
+ # the available tag types until the tag answers the request.
219
+ #
220
+ # Currently the following tag types are supported:
221
+ #
222
+ # * Mifare Classic
223
+ # * NFC Forum Type 1
224
+ # * NFC Forum Type 2
225
+ # * NFC Forum Type 3
226
+ # * NFC Forum Type 4
227
+ #
228
+ # After you call BrickletNFC#reader_request_tag_id the NFC Bricklet will try to read
229
+ # the tag ID from the tag. After this process is done the state will change.
230
+ # You can either register the CALLBACK_READER_STATE_CHANGED callback or you can poll
231
+ # BrickletNFC#reader_get_state to find out about the state change.
232
+ #
233
+ # If the state changes to *ReaderRequestTagIDError* it means that either there was
234
+ # no tag present or that the tag has an incompatible type. If the state
235
+ # changes to *ReaderRequestTagIDReady* it means that a compatible tag was found
236
+ # and that the tag ID has been saved. You can now read out the tag ID by
237
+ # calling BrickletNFC#reader_get_tag_id.
238
+ #
239
+ # If two tags are in the proximity of the NFC Bricklet, this
240
+ # function will cycle through the tags. To select a specific tag you have
241
+ # to call BrickletNFC#reader_request_tag_id until the correct tag ID is found.
242
+ #
243
+ # In case of any *ReaderError* state the selection is lost and you have to
244
+ # start again by calling BrickletNFC#reader_request_tag_id.
245
+ def reader_request_tag_id
246
+ send_request FUNCTION_READER_REQUEST_TAG_ID, [], '', 0, ''
247
+ end
248
+
249
+ # Returns the tag type and the tag ID. This function can only be called if the
250
+ # NFC Bricklet is currently in one of the *ReaderReady* states. The returned tag ID
251
+ # is the tag ID that was saved through the last call of BrickletNFC#reader_request_tag_id.
252
+ #
253
+ # To get the tag ID of a tag the approach is as follows:
254
+ #
255
+ # 1. Call BrickletNFC#reader_request_tag_id
256
+ # 2. Wait for state to change to *ReaderRequestTagIDReady* (see BrickletNFC#reader_get_state or
257
+ # CALLBACK_READER_STATE_CHANGED callback)
258
+ # 3. Call BrickletNFC#reader_get_tag_id
259
+ def reader_get_tag_id_low_level
260
+ send_request FUNCTION_READER_GET_TAG_ID_LOW_LEVEL, [], '', 34, 'C C C32'
261
+ end
262
+
263
+ # Returns the current reader state of the NFC Bricklet.
264
+ #
265
+ # On startup the Bricklet will be in the *ReaderInitialization* state. The
266
+ # initialization will only take about 20ms. After that it changes to *ReaderIdle*.
267
+ #
268
+ # The Bricklet is also reinitialized if the mode is changed, see BrickletNFC#set_mode.
269
+ #
270
+ # The functions of this Bricklet can be called in the *ReaderIdle* state and all of
271
+ # the *ReaderReady* and *ReaderError* states.
272
+ #
273
+ # Example: If you call BrickletNFC#reader_request_page, the state will change to
274
+ # *ReaderRequestPage* until the reading of the page is finished. Then it will change
275
+ # to either *ReaderRequestPageReady* if it worked or to *ReaderRequestPageError* if it
276
+ # didn't. If the request worked you can get the page by calling BrickletNFC#reader_read_page.
277
+ #
278
+ # The same approach is used analogously for the other API functions.
279
+ def reader_get_state
280
+ send_request FUNCTION_READER_GET_STATE, [], '', 2, 'C ?'
281
+ end
282
+
283
+ # Writes NDEF formated data with a maximum of 255 bytes.
284
+ #
285
+ # This function currently supports NFC Forum Type 2 and 4.
286
+ #
287
+ # The general approach for writing a NDEF message is as follows:
288
+ #
289
+ # 1. Call BrickletNFC#reader_request_tag_id
290
+ # 2. Wait for state to change to *ReaderRequestTagIDReady* (see
291
+ # BrickletNFC#reader_get_state or CALLBACK_READER_STATE_CHANGED callback)
292
+ # 3. If looking for a specific tag then call BrickletNFC#reader_get_tag_id and check
293
+ # if the expected tag was found, if it was not found got back to step 1
294
+ # 4. Call BrickletNFC#reader_write_ndef with the NDEF message that you want to write
295
+ # 5. Wait for state to change to *ReaderWriteNDEFReady* (see BrickletNFC#reader_get_state
296
+ # or CALLBACK_READER_STATE_CHANGED callback)
297
+ def reader_write_ndef_low_level(ndef_length, ndef_chunk_offset, ndef_chunk_data)
298
+ send_request FUNCTION_READER_WRITE_NDEF_LOW_LEVEL, [ndef_length, ndef_chunk_offset, ndef_chunk_data], 'S S C60', 0, ''
299
+ end
300
+
301
+ # Reads NDEF formated data from a tag.
302
+ #
303
+ # This function currently supports NFC Forum Type 1, 2, 3 and 4.
304
+ #
305
+ # The general approach for reading a NDEF message is as follows:
306
+ #
307
+ # 1. Call BrickletNFC#reader_request_tag_id
308
+ # 2. Wait for state to change to *RequestTagIDReady* (see BrickletNFC#reader_get_state
309
+ # or CALLBACK_READER_STATE_CHANGED callback)
310
+ # 3. If looking for a specific tag then call BrickletNFC#reader_get_tag_id and check if the
311
+ # expected tag was found, if it was not found got back to step 1
312
+ # 4. Call BrickletNFC#reader_request_ndef
313
+ # 5. Wait for state to change to *ReaderRequestNDEFReady* (see BrickletNFC#reader_get_state
314
+ # or CALLBACK_READER_STATE_CHANGED callback)
315
+ # 6. Call BrickletNFC#reader_read_ndef to retrieve the NDEF message from the buffer
316
+ def reader_request_ndef
317
+ send_request FUNCTION_READER_REQUEST_NDEF, [], '', 0, ''
318
+ end
319
+
320
+ # Returns the NDEF data from an internal buffer. To fill the buffer
321
+ # with a NDEF message you have to call BrickletNFC#reader_request_ndef beforehand.
322
+ #
323
+ # The buffer can have a size of up to 8192 bytes.
324
+ def reader_read_ndef_low_level
325
+ send_request FUNCTION_READER_READ_NDEF_LOW_LEVEL, [], '', 64, 'S S C60'
326
+ end
327
+
328
+ # Mifare Classic tags use authentication. If you want to read from or write to
329
+ # a Mifare Classic page you have to authenticate it beforehand.
330
+ # Each page can be authenticated with two keys: A (``key_number`` = 0) and B
331
+ # (``key_number`` = 1). A new Mifare Classic
332
+ # tag that has not yet been written to can be accessed with key A
333
+ # and the default key ``[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]``.
334
+ #
335
+ # The approach to read or write a Mifare Classic page is as follows:
336
+ #
337
+ # 1. Call BrickletNFC#reader_request_tag_id
338
+ # 2. Wait for state to change to *ReaderRequestTagIDReady* (see BrickletNFC#reader_get_state
339
+ # or CALLBACK_READER_STATE_CHANGED callback)
340
+ # 3. If looking for a specific tag then call BrickletNFC#reader_get_tag_id and check if the
341
+ # expected tag was found, if it was not found got back to step 1
342
+ # 4. Call BrickletNFC#reader_authenticate_mifare_classic_page with page and key for the page
343
+ # 5. Wait for state to change to *ReaderAuthenticatingMifareClassicPageReady* (see
344
+ # BrickletNFC#reader_get_state or CALLBACK_READER_STATE_CHANGED callback)
345
+ # 6. Call BrickletNFC#reader_request_page or BrickletNFC#reader_write_page to read/write page
346
+ #
347
+ # The authentication will always work for one whole sector (4 pages).
348
+ def reader_authenticate_mifare_classic_page(page, key_number, key)
349
+ send_request FUNCTION_READER_AUTHENTICATE_MIFARE_CLASSIC_PAGE, [page, key_number, key], 'S C C6', 0, ''
350
+ end
351
+
352
+ # Writes a maximum of 8192 bytes starting from the given page. How many pages are written
353
+ # depends on the tag type. The page sizes are as follows:
354
+ #
355
+ # * Mifare Classic page size: 16 byte
356
+ # * NFC Forum Type 1 page size: 8 byte
357
+ # * NFC Forum Type 2 page size: 4 byte
358
+ # * NFC Forum Type 3 page size: 16 byte
359
+ # * NFC Forum Type 4: No pages, page = file selection (CC or NDEF, see below)
360
+ #
361
+ # The general approach for writing to a tag is as follows:
362
+ #
363
+ # 1. Call BrickletNFC#reader_request_tag_id
364
+ # 2. Wait for state to change to *ReaderRequestTagIDReady* (see BrickletNFC#reader_get_state or
365
+ # CALLBACK_READER_STATE_CHANGED callback)
366
+ # 3. If looking for a specific tag then call BrickletNFC#reader_get_tag_id and check if the
367
+ # expected tag was found, if it was not found got back to step 1
368
+ # 4. Call BrickletNFC#reader_write_page with page number and data
369
+ # 5. Wait for state to change to *ReaderWritePageReady* (see BrickletNFC#reader_get_state or
370
+ # CALLBACK_READER_STATE_CHANGED callback)
371
+ #
372
+ # If you use a Mifare Classic tag you have to authenticate a page before you
373
+ # can write to it. See BrickletNFC#reader_authenticate_mifare_classic_page.
374
+ #
375
+ # NFC Forum Type 4 tags are not organized into pages but different files. We currently
376
+ # support two files: Capability Container file (CC) and NDEF file.
377
+ #
378
+ # Choose CC by setting page to 3 or NDEF by setting page to 4.
379
+ def reader_write_page_low_level(page, data_length, data_chunk_offset, data_chunk_data)
380
+ send_request FUNCTION_READER_WRITE_PAGE_LOW_LEVEL, [page, data_length, data_chunk_offset, data_chunk_data], 'S S S C58', 0, ''
381
+ end
382
+
383
+ # Reads a maximum of 8192 bytes starting from the given page and stores them into a buffer.
384
+ # The buffer can then be read out with BrickletNFC#reader_read_page.
385
+ # How many pages are read depends on the tag type. The page sizes are
386
+ # as follows:
387
+ #
388
+ # * Mifare Classic page size: 16 byte
389
+ # * NFC Forum Type 1 page size: 8 byte
390
+ # * NFC Forum Type 2 page size: 4 byte
391
+ # * NFC Forum Type 3 page size: 16 byte
392
+ # * NFC Forum Type 4: No pages, page = file selection (CC or NDEF, see below)
393
+ #
394
+ # The general approach for reading a tag is as follows:
395
+ #
396
+ # 1. Call BrickletNFC#reader_request_tag_id
397
+ # 2. Wait for state to change to *RequestTagIDReady* (see BrickletNFC#reader_get_state
398
+ # or CALLBACK_READER_STATE_CHANGED callback)
399
+ # 3. If looking for a specific tag then call BrickletNFC#reader_get_tag_id and check if the
400
+ # expected tag was found, if it was not found got back to step 1
401
+ # 4. Call BrickletNFC#reader_request_page with page number
402
+ # 5. Wait for state to change to *ReaderRequestPageReady* (see BrickletNFC#reader_get_state
403
+ # or CALLBACK_READER_STATE_CHANGED callback)
404
+ # 6. Call BrickletNFC#reader_read_page to retrieve the page from the buffer
405
+ #
406
+ # If you use a Mifare Classic tag you have to authenticate a page before you
407
+ # can read it. See BrickletNFC#reader_authenticate_mifare_classic_page.
408
+ #
409
+ # NFC Forum Type 4 tags are not organized into pages but different files. We currently
410
+ # support two files: Capability Container file (CC) and NDEF file.
411
+ #
412
+ # Choose CC by setting page to 3 or NDEF by setting page to 4.
413
+ def reader_request_page(page, length)
414
+ send_request FUNCTION_READER_REQUEST_PAGE, [page, length], 'S S', 0, ''
415
+ end
416
+
417
+ # Returns the page data from an internal buffer. To fill the buffer
418
+ # with specific pages you have to call BrickletNFC#reader_request_page beforehand.
419
+ #
420
+ # The buffer can have a size of up to 8192 bytes.
421
+ def reader_read_page_low_level
422
+ send_request FUNCTION_READER_READ_PAGE_LOW_LEVEL, [], '', 64, 'S S C60'
423
+ end
424
+
425
+ # Returns the current cardemu state of the NFC Bricklet.
426
+ #
427
+ # On startup the Bricklet will be in the *CardemuInitialization* state. The
428
+ # initialization will only take about 20ms. After that it changes to *CardemuIdle*.
429
+ #
430
+ # The Bricklet is also reinitialized if the mode is changed, see BrickletNFC#set_mode.
431
+ #
432
+ # The functions of this Bricklet can be called in the *CardemuIdle* state and all of
433
+ # the *CardemuReady* and *CardemuError* states.
434
+ #
435
+ # Example: If you call BrickletNFC#cardemu_start_discovery, the state will change to
436
+ # *CardemuDiscover* until the discovery is finished. Then it will change
437
+ # to either *CardemuDiscoverReady* if it worked or to *CardemuDiscoverError* if it
438
+ # didn't.
439
+ #
440
+ # The same approach is used analogously for the other API functions.
441
+ def cardemu_get_state
442
+ send_request FUNCTION_CARDEMU_GET_STATE, [], '', 2, 'C ?'
443
+ end
444
+
445
+ # Starts the discovery process. If you call this function while a NFC
446
+ # reader device is near to the NFC Bricklet the state will change from
447
+ # *CardemuDiscovery* to *CardemuDiscoveryReady*.
448
+ #
449
+ # If no NFC reader device can be found or if there is an error during
450
+ # discovery the cardemu state will change to *CardemuDiscoveryError*. In this case you
451
+ # have to restart the discovery process.
452
+ #
453
+ # If the cardemu state changes to *CardemuDiscoveryReady* you can start the NDEF message
454
+ # transfer with BrickletNFC#cardemu_write_ndef and BrickletNFC#cardemu_start_transfer.
455
+ def cardemu_start_discovery
456
+ send_request FUNCTION_CARDEMU_START_DISCOVERY, [], '', 0, ''
457
+ end
458
+
459
+ # Writes the NDEF messages that is to be transferred to the NFC peer.
460
+ #
461
+ # The maximum supported NDEF message size in Cardemu mode is 255 byte.
462
+ #
463
+ # You can call this function at any time in Cardemu mode. The internal buffer
464
+ # will not be overwritten until you call this function again or change the
465
+ # mode.
466
+ def cardemu_write_ndef_low_level(ndef_length, ndef_chunk_offset, ndef_chunk_data)
467
+ send_request FUNCTION_CARDEMU_WRITE_NDEF_LOW_LEVEL, [ndef_length, ndef_chunk_offset, ndef_chunk_data], 'S S C60', 0, ''
468
+ end
469
+
470
+ # You can start the transfer of a NDEF message if the cardemu state is *CardemuDiscoveryReady*.
471
+ #
472
+ # Before you call this function to start a write transfer, the NDEF message that
473
+ # is to be transferred has to be written via BrickletNFC#cardemu_write_ndef first.
474
+ #
475
+ # After you call this function the state will change to *CardemuTransferNDEF*. It will
476
+ # change to *CardemuTransferNDEFReady* if the transfer was successful or
477
+ # *CardemuTransferNDEFError* if it wasn't.
478
+ def cardemu_start_transfer(transfer)
479
+ send_request FUNCTION_CARDEMU_START_TRANSFER, [transfer], 'C', 0, ''
480
+ end
481
+
482
+ # Returns the current P2P state of the NFC Bricklet.
483
+ #
484
+ # On startup the Bricklet will be in the *P2PInitialization* state. The
485
+ # initialization will only take about 20ms. After that it changes to *P2PIdle*.
486
+ #
487
+ # The Bricklet is also reinitialized if the mode is changed, see BrickletNFC#set_mode.
488
+ #
489
+ # The functions of this Bricklet can be called in the *P2PIdle* state and all of
490
+ # the *P2PReady* and *P2PError* states.
491
+ #
492
+ # Example: If you call BrickletNFC#p2p_start_discovery, the state will change to
493
+ # *P2PDiscover* until the discovery is finished. Then it will change
494
+ # to either P2PDiscoverReady* if it worked or to *P2PDiscoverError* if it
495
+ # didn't.
496
+ #
497
+ # The same approach is used analogously for the other API functions.
498
+ def p2p_get_state
499
+ send_request FUNCTION_P2P_GET_STATE, [], '', 2, 'C ?'
500
+ end
501
+
502
+ # Starts the discovery process. If you call this function while another NFC
503
+ # P2P enabled device is near to the NFC Bricklet the state will change from
504
+ # *P2PDiscovery* to *P2PDiscoveryReady*.
505
+ #
506
+ # If no NFC P2P enabled device can be found or if there is an error during
507
+ # discovery the P2P state will change to *P2PDiscoveryError*. In this case you
508
+ # have to restart the discovery process.
509
+ #
510
+ # If the P2P state changes to *P2PDiscoveryReady* you can start the NDEF message
511
+ # transfer with BrickletNFC#p2p_start_transfer.
512
+ def p2p_start_discovery
513
+ send_request FUNCTION_P2P_START_DISCOVERY, [], '', 0, ''
514
+ end
515
+
516
+ # Writes the NDEF messages that is to be transferred to the NFC peer.
517
+ #
518
+ # The maximum supported NDEF message size for P2P transfer is 255 byte.
519
+ #
520
+ # You can call this function at any time in P2P mode. The internal buffer
521
+ # will not be overwritten until you call this function again, change the
522
+ # mode or use P2P to read an NDEF messages.
523
+ def p2p_write_ndef_low_level(ndef_length, ndef_chunk_offset, ndef_chunk_data)
524
+ send_request FUNCTION_P2P_WRITE_NDEF_LOW_LEVEL, [ndef_length, ndef_chunk_offset, ndef_chunk_data], 'S S C60', 0, ''
525
+ end
526
+
527
+ # You can start the transfer of a NDEF message if the P2P state is *P2PDiscoveryReady*.
528
+ #
529
+ # Before you call this function to start a write transfer, the NDEF message that
530
+ # is to be transferred has to be written via BrickletNFC#p2p_write_ndef first.
531
+ #
532
+ # After you call this function the P2P state will change to *P2PTransferNDEF*. It will
533
+ # change to *P2PTransferNDEFReady* if the transfer was successfull or
534
+ # *P2PTransferNDEFError* if it wasn't.
535
+ #
536
+ # If you started a write transfer you are now done. If you started a read transfer
537
+ # you can now use BrickletNFC#p2p_read_ndef to read the NDEF message that was written
538
+ # by the NFC peer.
539
+ def p2p_start_transfer(transfer)
540
+ send_request FUNCTION_P2P_START_TRANSFER, [transfer], 'C', 0, ''
541
+ end
542
+
543
+ # Returns the NDEF message that was written by a NFC peer in NFC P2P mode.
544
+ # The maximum NDEF length is 8192 byte.
545
+ #
546
+ # The NDEF message is ready if you called BrickletNFC#p2p_start_transfer with a
547
+ # read transfer and the P2P state changed to *P2PTransferNDEFReady*.
548
+ def p2p_read_ndef_low_level
549
+ send_request FUNCTION_P2P_READ_NDEF_LOW_LEVEL, [], '', 64, 'S S C60'
550
+ end
551
+
552
+ # Sets the detection LED configuration. By default the LED shows
553
+ # if a card/reader is detected.
554
+ #
555
+ # You can also turn the LED permanently on/off or show a heartbeat.
556
+ #
557
+ # If the Bricklet is in bootloader mode, the LED is off.
558
+ def set_detection_led_config(config)
559
+ send_request FUNCTION_SET_DETECTION_LED_CONFIG, [config], 'C', 0, ''
560
+ end
561
+
562
+ # Returns the configuration as set by BrickletNFC#set_detection_led_config
563
+ def get_detection_led_config
564
+ send_request FUNCTION_GET_DETECTION_LED_CONFIG, [], '', 1, 'C'
565
+ end
566
+
567
+ # Returns the error count for the communication between Brick and Bricklet.
568
+ #
569
+ # The errors are divided into
570
+ #
571
+ # * ack checksum errors,
572
+ # * message checksum errors,
573
+ # * frameing errors and
574
+ # * overflow errors.
575
+ #
576
+ # The errors counts are for errors that occur on the Bricklet side. All
577
+ # Bricks have a similar function that returns the errors on the Brick side.
578
+ def get_spitfp_error_count
579
+ send_request FUNCTION_GET_SPITFP_ERROR_COUNT, [], '', 16, 'L L L L'
580
+ end
581
+
582
+ # Sets the bootloader mode and returns the status after the requested
583
+ # mode change was instigated.
584
+ #
585
+ # You can change from bootloader mode to firmware mode and vice versa. A change
586
+ # from bootloader mode to firmware mode will only take place if the entry function,
587
+ # device identifier und crc are present and correct.
588
+ #
589
+ # This function is used by Brick Viewer during flashing. It should not be
590
+ # necessary to call it in a normal user program.
591
+ def set_bootloader_mode(mode)
592
+ send_request FUNCTION_SET_BOOTLOADER_MODE, [mode], 'C', 1, 'C'
593
+ end
594
+
595
+ # Returns the current bootloader mode, see BrickletNFC#set_bootloader_mode.
596
+ def get_bootloader_mode
597
+ send_request FUNCTION_GET_BOOTLOADER_MODE, [], '', 1, 'C'
598
+ end
599
+
600
+ # Sets the firmware pointer for BrickletNFC#write_firmware. The pointer has
601
+ # to be increased by chunks of size 64. The data is written to flash
602
+ # every 4 chunks (which equals to one page of size 256).
603
+ #
604
+ # This function is used by Brick Viewer during flashing. It should not be
605
+ # necessary to call it in a normal user program.
606
+ def set_write_firmware_pointer(pointer)
607
+ send_request FUNCTION_SET_WRITE_FIRMWARE_POINTER, [pointer], 'L', 0, ''
608
+ end
609
+
610
+ # Writes 64 Bytes of firmware at the position as written by
611
+ # BrickletNFC#set_write_firmware_pointer before. The firmware is written
612
+ # to flash every 4 chunks.
613
+ #
614
+ # You can only write firmware in bootloader mode.
615
+ #
616
+ # This function is used by Brick Viewer during flashing. It should not be
617
+ # necessary to call it in a normal user program.
618
+ def write_firmware(data)
619
+ send_request FUNCTION_WRITE_FIRMWARE, [data], 'C64', 1, 'C'
620
+ end
621
+
622
+ # Sets the status LED configuration. By default the LED shows
623
+ # communication traffic between Brick and Bricklet, it flickers once
624
+ # for every 10 received data packets.
625
+ #
626
+ # You can also turn the LED permanently on/off or show a heartbeat.
627
+ #
628
+ # If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
629
+ def set_status_led_config(config)
630
+ send_request FUNCTION_SET_STATUS_LED_CONFIG, [config], 'C', 0, ''
631
+ end
632
+
633
+ # Returns the configuration as set by BrickletNFC#set_status_led_config
634
+ def get_status_led_config
635
+ send_request FUNCTION_GET_STATUS_LED_CONFIG, [], '', 1, 'C'
636
+ end
637
+
638
+ # Returns the temperature in °C as measured inside the microcontroller. The
639
+ # value returned is not the ambient temperature!
640
+ #
641
+ # The temperature is only proportional to the real temperature and it has bad
642
+ # accuracy. Practically it is only useful as an indicator for
643
+ # temperature changes.
644
+ def get_chip_temperature
645
+ send_request FUNCTION_GET_CHIP_TEMPERATURE, [], '', 2, 's'
646
+ end
647
+
648
+ # Calling this function will reset the Bricklet. All configurations
649
+ # will be lost.
650
+ #
651
+ # After a reset you have to create new device objects,
652
+ # calling functions on the existing ones will result in
653
+ # undefined behavior!
654
+ def reset
655
+ send_request FUNCTION_RESET, [], '', 0, ''
656
+ end
657
+
658
+ # Writes a new UID into flash. If you want to set a new UID
659
+ # you have to decode the Base58 encoded UID string into an
660
+ # integer first.
661
+ #
662
+ # We recommend that you use Brick Viewer to change the UID.
663
+ def write_uid(uid)
664
+ send_request FUNCTION_WRITE_UID, [uid], 'L', 0, ''
665
+ end
666
+
667
+ # Returns the current UID as an integer. Encode as
668
+ # Base58 to get the usual string version.
669
+ def read_uid
670
+ send_request FUNCTION_READ_UID, [], '', 4, 'L'
671
+ end
672
+
673
+ # Returns the UID, the UID where the Bricklet is connected to,
674
+ # the position, the hardware and firmware version as well as the
675
+ # device identifier.
676
+ #
677
+ # The position can be 'a', 'b', 'c' or 'd'.
678
+ #
679
+ # The device identifier numbers can be found :ref:`here <device_identifier>`.
680
+ # |device_identifier_constant|
681
+ def get_identity
682
+ send_request FUNCTION_GET_IDENTITY, [], '', 25, 'Z8 Z8 k C3 C3 S'
683
+ end
684
+
685
+ # Returns the tag type and the tag ID. This function can only be called if the
686
+ # NFC Bricklet is currently in one of the *ReaderReady* states. The returned tag ID
687
+ # is the tag ID that was saved through the last call of BrickletNFC#reader_request_tag_id.
688
+ #
689
+ # To get the tag ID of a tag the approach is as follows:
690
+ #
691
+ # 1. Call BrickletNFC#reader_request_tag_id
692
+ # 2. Wait for state to change to *ReaderRequestTagIDReady* (see BrickletNFC#reader_get_state or
693
+ # CALLBACK_READER_STATE_CHANGED callback)
694
+ # 3. Call BrickletNFC#reader_get_tag_id
695
+ def reader_get_tag_id
696
+ ret = reader_get_tag_id_low_level
697
+
698
+ [ret[0], ret[2][0, ret[1]]]
699
+ end
700
+
701
+ # Writes NDEF formated data with a maximum of 255 bytes.
702
+ #
703
+ # This function currently supports NFC Forum Type 2 and 4.
704
+ #
705
+ # The general approach for writing a NDEF message is as follows:
706
+ #
707
+ # 1. Call BrickletNFC#reader_request_tag_id
708
+ # 2. Wait for state to change to *ReaderRequestTagIDReady* (see
709
+ # BrickletNFC#reader_get_state or CALLBACK_READER_STATE_CHANGED callback)
710
+ # 3. If looking for a specific tag then call BrickletNFC#reader_get_tag_id and check
711
+ # if the expected tag was found, if it was not found got back to step 1
712
+ # 4. Call BrickletNFC#reader_write_ndef with the NDEF message that you want to write
713
+ # 5. Wait for state to change to *ReaderWriteNDEFReady* (see BrickletNFC#reader_get_state
714
+ # or CALLBACK_READER_STATE_CHANGED callback)
715
+ def reader_write_ndef(ndef)
716
+ if ndef.length > 65535
717
+ raise ArgumentError, 'NDEF can be at most 65535 items long'
718
+ end
719
+
720
+ ndef_length = ndef.length
721
+ ndef_chunk_offset = 0
722
+
723
+ if ndef_length == 0
724
+ ndef_chunk_data = [0] * 60
725
+ ret = reader_write_ndef_low_level ndef_length, ndef_chunk_offset, ndef_chunk_data
726
+ else
727
+ ret = nil # assigned in block
728
+
729
+ @stream_mutex.synchronize {
730
+ while ndef_chunk_offset < ndef_length
731
+ ndef_chunk_data = ndef[ndef_chunk_offset, 60]
732
+
733
+ if ndef_chunk_data.length < 60
734
+ ndef_chunk_data += [0] * (60 - ndef_chunk_data.length)
735
+ end
736
+
737
+ ret = reader_write_ndef_low_level ndef_length, ndef_chunk_offset, ndef_chunk_data
738
+ ndef_chunk_offset += 60
739
+ end
740
+ }
741
+ end
742
+
743
+ ret
744
+ end
745
+
746
+ # Returns the NDEF data from an internal buffer. To fill the buffer
747
+ # with a NDEF message you have to call BrickletNFC#reader_request_ndef beforehand.
748
+ #
749
+ # The buffer can have a size of up to 8192 bytes.
750
+ def reader_read_ndef
751
+ ndef_length = nil # assigned in block
752
+ ndef_data = nil # assigned in block
753
+
754
+ @stream_mutex.synchronize {
755
+ ret = reader_read_ndef_low_level
756
+ ndef_length = ret[0]
757
+ ndef_chunk_offset = ret[1]
758
+ ndef_out_of_sync = ndef_chunk_offset != 0
759
+ ndef_data = ret[2]
760
+
761
+ while not ndef_out_of_sync and ndef_data.length < ndef_length
762
+ ret = reader_read_ndef_low_level
763
+ ndef_length = ret[0]
764
+ ndef_chunk_offset = ret[1]
765
+ ndef_out_of_sync = ndef_chunk_offset != ndef_data.length
766
+ ndef_data += ret[2]
767
+ end
768
+
769
+ if ndef_out_of_sync # discard remaining stream to bring it back in-sync
770
+ while ndef_chunk_offset + 60 < ndef_length
771
+ ret = reader_read_ndef_low_level
772
+ ndef_length = ret[0]
773
+ ndef_chunk_offset = ret[1]
774
+ end
775
+
776
+ raise StreamOutOfSyncException, 'NDEF stream is out-of-sync'
777
+ end
778
+ }
779
+
780
+ ndef_data[0, ndef_length]
781
+ end
782
+
783
+ # Writes a maximum of 8192 bytes starting from the given page. How many pages are written
784
+ # depends on the tag type. The page sizes are as follows:
785
+ #
786
+ # * Mifare Classic page size: 16 byte
787
+ # * NFC Forum Type 1 page size: 8 byte
788
+ # * NFC Forum Type 2 page size: 4 byte
789
+ # * NFC Forum Type 3 page size: 16 byte
790
+ # * NFC Forum Type 4: No pages, page = file selection (CC or NDEF, see below)
791
+ #
792
+ # The general approach for writing to a tag is as follows:
793
+ #
794
+ # 1. Call BrickletNFC#reader_request_tag_id
795
+ # 2. Wait for state to change to *ReaderRequestTagIDReady* (see BrickletNFC#reader_get_state or
796
+ # CALLBACK_READER_STATE_CHANGED callback)
797
+ # 3. If looking for a specific tag then call BrickletNFC#reader_get_tag_id and check if the
798
+ # expected tag was found, if it was not found got back to step 1
799
+ # 4. Call BrickletNFC#reader_write_page with page number and data
800
+ # 5. Wait for state to change to *ReaderWritePageReady* (see BrickletNFC#reader_get_state or
801
+ # CALLBACK_READER_STATE_CHANGED callback)
802
+ #
803
+ # If you use a Mifare Classic tag you have to authenticate a page before you
804
+ # can write to it. See BrickletNFC#reader_authenticate_mifare_classic_page.
805
+ #
806
+ # NFC Forum Type 4 tags are not organized into pages but different files. We currently
807
+ # support two files: Capability Container file (CC) and NDEF file.
808
+ #
809
+ # Choose CC by setting page to 3 or NDEF by setting page to 4.
810
+ def reader_write_page(page, data)
811
+ if data.length > 65535
812
+ raise ArgumentError, 'Data can be at most 65535 items long'
813
+ end
814
+
815
+ data_length = data.length
816
+ data_chunk_offset = 0
817
+
818
+ if data_length == 0
819
+ data_chunk_data = [0] * 58
820
+ ret = reader_write_page_low_level page, data_length, data_chunk_offset, data_chunk_data
821
+ else
822
+ ret = nil # assigned in block
823
+
824
+ @stream_mutex.synchronize {
825
+ while data_chunk_offset < data_length
826
+ data_chunk_data = data[data_chunk_offset, 58]
827
+
828
+ if data_chunk_data.length < 58
829
+ data_chunk_data += [0] * (58 - data_chunk_data.length)
830
+ end
831
+
832
+ ret = reader_write_page_low_level page, data_length, data_chunk_offset, data_chunk_data
833
+ data_chunk_offset += 58
834
+ end
835
+ }
836
+ end
837
+
838
+ ret
839
+ end
840
+
841
+ # Returns the page data from an internal buffer. To fill the buffer
842
+ # with specific pages you have to call BrickletNFC#reader_request_page beforehand.
843
+ #
844
+ # The buffer can have a size of up to 8192 bytes.
845
+ def reader_read_page
846
+ data_length = nil # assigned in block
847
+ data_data = nil # assigned in block
848
+
849
+ @stream_mutex.synchronize {
850
+ ret = reader_read_page_low_level
851
+ data_length = ret[0]
852
+ data_chunk_offset = ret[1]
853
+ data_out_of_sync = data_chunk_offset != 0
854
+ data_data = ret[2]
855
+
856
+ while not data_out_of_sync and data_data.length < data_length
857
+ ret = reader_read_page_low_level
858
+ data_length = ret[0]
859
+ data_chunk_offset = ret[1]
860
+ data_out_of_sync = data_chunk_offset != data_data.length
861
+ data_data += ret[2]
862
+ end
863
+
864
+ if data_out_of_sync # discard remaining stream to bring it back in-sync
865
+ while data_chunk_offset + 60 < data_length
866
+ ret = reader_read_page_low_level
867
+ data_length = ret[0]
868
+ data_chunk_offset = ret[1]
869
+ end
870
+
871
+ raise StreamOutOfSyncException, 'Data stream is out-of-sync'
872
+ end
873
+ }
874
+
875
+ data_data[0, data_length]
876
+ end
877
+
878
+ # Writes the NDEF messages that is to be transferred to the NFC peer.
879
+ #
880
+ # The maximum supported NDEF message size in Cardemu mode is 255 byte.
881
+ #
882
+ # You can call this function at any time in Cardemu mode. The internal buffer
883
+ # will not be overwritten until you call this function again or change the
884
+ # mode.
885
+ def cardemu_write_ndef(ndef)
886
+ if ndef.length > 65535
887
+ raise ArgumentError, 'NDEF can be at most 65535 items long'
888
+ end
889
+
890
+ ndef_length = ndef.length
891
+ ndef_chunk_offset = 0
892
+
893
+ if ndef_length == 0
894
+ ndef_chunk_data = [0] * 60
895
+ ret = cardemu_write_ndef_low_level ndef_length, ndef_chunk_offset, ndef_chunk_data
896
+ else
897
+ ret = nil # assigned in block
898
+
899
+ @stream_mutex.synchronize {
900
+ while ndef_chunk_offset < ndef_length
901
+ ndef_chunk_data = ndef[ndef_chunk_offset, 60]
902
+
903
+ if ndef_chunk_data.length < 60
904
+ ndef_chunk_data += [0] * (60 - ndef_chunk_data.length)
905
+ end
906
+
907
+ ret = cardemu_write_ndef_low_level ndef_length, ndef_chunk_offset, ndef_chunk_data
908
+ ndef_chunk_offset += 60
909
+ end
910
+ }
911
+ end
912
+
913
+ ret
914
+ end
915
+
916
+ # Writes the NDEF messages that is to be transferred to the NFC peer.
917
+ #
918
+ # The maximum supported NDEF message size for P2P transfer is 255 byte.
919
+ #
920
+ # You can call this function at any time in P2P mode. The internal buffer
921
+ # will not be overwritten until you call this function again, change the
922
+ # mode or use P2P to read an NDEF messages.
923
+ def p2p_write_ndef(ndef)
924
+ if ndef.length > 65535
925
+ raise ArgumentError, 'NDEF can be at most 65535 items long'
926
+ end
927
+
928
+ ndef_length = ndef.length
929
+ ndef_chunk_offset = 0
930
+
931
+ if ndef_length == 0
932
+ ndef_chunk_data = [0] * 60
933
+ ret = p2p_write_ndef_low_level ndef_length, ndef_chunk_offset, ndef_chunk_data
934
+ else
935
+ ret = nil # assigned in block
936
+
937
+ @stream_mutex.synchronize {
938
+ while ndef_chunk_offset < ndef_length
939
+ ndef_chunk_data = ndef[ndef_chunk_offset, 60]
940
+
941
+ if ndef_chunk_data.length < 60
942
+ ndef_chunk_data += [0] * (60 - ndef_chunk_data.length)
943
+ end
944
+
945
+ ret = p2p_write_ndef_low_level ndef_length, ndef_chunk_offset, ndef_chunk_data
946
+ ndef_chunk_offset += 60
947
+ end
948
+ }
949
+ end
950
+
951
+ ret
952
+ end
953
+
954
+ # Returns the NDEF message that was written by a NFC peer in NFC P2P mode.
955
+ # The maximum NDEF length is 8192 byte.
956
+ #
957
+ # The NDEF message is ready if you called BrickletNFC#p2p_start_transfer with a
958
+ # read transfer and the P2P state changed to *P2PTransferNDEFReady*.
959
+ def p2p_read_ndef
960
+ ndef_length = nil # assigned in block
961
+ ndef_data = nil # assigned in block
962
+
963
+ @stream_mutex.synchronize {
964
+ ret = p2p_read_ndef_low_level
965
+ ndef_length = ret[0]
966
+ ndef_chunk_offset = ret[1]
967
+ ndef_out_of_sync = ndef_chunk_offset != 0
968
+ ndef_data = ret[2]
969
+
970
+ while not ndef_out_of_sync and ndef_data.length < ndef_length
971
+ ret = p2p_read_ndef_low_level
972
+ ndef_length = ret[0]
973
+ ndef_chunk_offset = ret[1]
974
+ ndef_out_of_sync = ndef_chunk_offset != ndef_data.length
975
+ ndef_data += ret[2]
976
+ end
977
+
978
+ if ndef_out_of_sync # discard remaining stream to bring it back in-sync
979
+ while ndef_chunk_offset + 60 < ndef_length
980
+ ret = p2p_read_ndef_low_level
981
+ ndef_length = ret[0]
982
+ ndef_chunk_offset = ret[1]
983
+ end
984
+
985
+ raise StreamOutOfSyncException, 'NDEF stream is out-of-sync'
986
+ end
987
+ }
988
+
989
+ ndef_data[0, ndef_length]
990
+ end
991
+
992
+ # Registers a callback with ID <tt>id</tt> to the block <tt>block</tt>.
993
+ def register_callback(id, &block)
994
+ callback = block
995
+ @registered_callbacks[id] = callback
996
+ end
997
+ end
998
+ end