Skip to content

Commit 5173a0e

Browse files
authored
Merge branch 'dev' into portasynthinca3/3893-js-backport
2 parents 02d4bb6 + 57c438d commit 5173a0e

File tree

13 files changed

+234
-16
lines changed

13 files changed

+234
-16
lines changed

applications/services/gui/canvas.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,21 @@ void canvas_draw_xbm(
512512
size_t height,
513513
const uint8_t* bitmap) {
514514
furi_check(canvas);
515+
canvas_draw_xbm_ex(canvas, x, y, width, height, IconRotation0, bitmap);
516+
}
517+
518+
void canvas_draw_xbm_ex(
519+
Canvas* canvas,
520+
int32_t x,
521+
int32_t y,
522+
size_t width,
523+
size_t height,
524+
IconRotation rotation,
525+
const uint8_t* bitmap_data) {
526+
furi_check(canvas);
515527
x += canvas->offset_x;
516528
y += canvas->offset_y;
517-
canvas_draw_u8g2_bitmap(&canvas->fb, x, y, width, height, bitmap, IconRotation0);
529+
canvas_draw_u8g2_bitmap(&canvas->fb, x, y, width, height, bitmap_data, rotation);
518530
}
519531

520532
void canvas_draw_glyph(Canvas* canvas, int32_t x, int32_t y, uint16_t ch) {

applications/services/gui/canvas.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,25 @@ void canvas_draw_xbm(
287287
size_t height,
288288
const uint8_t* bitmap);
289289

290+
/** Draw rotated XBM bitmap
291+
*
292+
* @param canvas Canvas instance
293+
* @param x x coordinate
294+
* @param y y coordinate
295+
* @param[in] width bitmap width
296+
* @param[in] height bitmap height
297+
* @param[in] rotation bitmap rotation
298+
* @param bitmap_data pointer to XBM bitmap data
299+
*/
300+
void canvas_draw_xbm_ex(
301+
Canvas* canvas,
302+
int32_t x,
303+
int32_t y,
304+
size_t width,
305+
size_t height,
306+
IconRotation rotation,
307+
const uint8_t* bitmap_data);
308+
290309
/** Draw dot at x,y
291310
*
292311
* @param canvas Canvas instance

firmware.scons

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ fwelf = fwenv["FW_ELF"] = fwenv.Program(
216216
sources,
217217
LIBS=fwenv["TARGET_CFG"].linker_dependencies,
218218
)
219+
Depends(fwelf, fwenv["LINKER_SCRIPT_PATH"])
219220

220221
# Firmware depends on everything child builders returned
221222
# Depends(fwelf, lib_targets)

lib/nfc/helpers/iso14443_4_layer.c

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,42 @@
22

33
#include <furi.h>
44

5-
#define ISO14443_4_BLOCK_PCB (1U << 1)
6-
#define ISO14443_4_BLOCK_PCB_I (0U)
7-
#define ISO14443_4_BLOCK_PCB_R (5U << 5)
8-
#define ISO14443_4_BLOCK_PCB_S (3U << 6)
5+
#define ISO14443_4_BLOCK_PCB (1U << 1)
6+
#define ISO14443_4_BLOCK_PCB_MASK (0x03)
7+
8+
#define ISO14443_4_BLOCK_PCB_I (0U)
9+
#define ISO14443_4_BLOCK_PCB_I_NAD_OFFSET (2)
10+
#define ISO14443_4_BLOCK_PCB_I_CID_OFFSET (3)
11+
#define ISO14443_4_BLOCK_PCB_I_CHAIN_OFFSET (4)
12+
#define ISO14443_4_BLOCK_PCB_I_NAD_MASK (1U << ISO14443_4_BLOCK_PCB_I_NAD_OFFSET)
13+
#define ISO14443_4_BLOCK_PCB_I_CID_MASK (1U << ISO14443_4_BLOCK_PCB_I_CID_OFFSET)
14+
#define ISO14443_4_BLOCK_PCB_I_CHAIN_MASK (1U << ISO14443_4_BLOCK_PCB_I_CHAIN_OFFSET)
15+
16+
#define ISO14443_4_BLOCK_PCB_R_MASK (5U << 5)
17+
#define ISO14443_4_BLOCK_PCB_R_NACK_OFFSET (4)
18+
#define ISO14443_4_BLOCK_PCB_R_CID_OFFSET (3)
19+
#define ISO14443_4_BLOCK_PCB_R_CID_MASK (1U << ISO14443_4_BLOCK_PCB_R_CID_OFFSET)
20+
#define ISO14443_4_BLOCK_PCB_R_NACK_MASK (1U << ISO14443_4_BLOCK_PCB_R_NACK_OFFSET)
21+
22+
#define ISO14443_4_BLOCK_PCB_S_MASK (3U << 6)
23+
#define ISO14443_4_BLOCK_PCB_S_CID_OFFSET (3)
24+
#define ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_OFFSET (4)
25+
#define ISO14443_4_BLOCK_PCB_S_CID_MASK (1U << ISO14443_4_BLOCK_PCB_R_CID_OFFSET)
26+
#define ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_MASK (3U << ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_OFFSET)
27+
28+
#define ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, mask) (((pcb) & (mask)) == (mask))
29+
30+
#define ISO14443_4_BLOCK_PCB_IS_R_BLOCK(pcb) \
31+
ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_R_MASK)
32+
33+
#define ISO14443_4_BLOCK_PCB_IS_S_BLOCK(pcb) \
34+
ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_S_MASK)
35+
36+
#define ISO14443_4_BLOCK_PCB_IS_CHAIN_ACTIVE(pcb) \
37+
ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_I_CHAIN_MASK)
38+
39+
#define ISO14443_4_BLOCK_PCB_R_NACK_ACTIVE(pcb) \
40+
ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_R_NACK_MASK)
941

1042
struct Iso14443_4Layer {
1143
uint8_t pcb;
@@ -31,9 +63,31 @@ void iso14443_4_layer_free(Iso14443_4Layer* instance) {
3163

3264
void iso14443_4_layer_reset(Iso14443_4Layer* instance) {
3365
furi_assert(instance);
66+
instance->pcb_prev = 0;
3467
instance->pcb = ISO14443_4_BLOCK_PCB_I | ISO14443_4_BLOCK_PCB;
3568
}
3669

70+
void iso14443_4_layer_set_i_block(Iso14443_4Layer* instance, bool chaining, bool CID_present) {
71+
uint8_t block_pcb = instance->pcb & ISO14443_4_BLOCK_PCB_MASK;
72+
instance->pcb = ISO14443_4_BLOCK_PCB_I | (chaining << ISO14443_4_BLOCK_PCB_I_CHAIN_OFFSET) |
73+
(CID_present << ISO14443_4_BLOCK_PCB_I_CID_OFFSET) | block_pcb;
74+
}
75+
76+
void iso14443_4_layer_set_r_block(Iso14443_4Layer* instance, bool acknowledged, bool CID_present) {
77+
furi_assert(instance);
78+
uint8_t block_pcb = instance->pcb & ISO14443_4_BLOCK_PCB_MASK;
79+
instance->pcb = ISO14443_4_BLOCK_PCB_R_MASK |
80+
(!acknowledged << ISO14443_4_BLOCK_PCB_R_NACK_OFFSET) |
81+
(CID_present << ISO14443_4_BLOCK_PCB_R_CID_OFFSET) | block_pcb;
82+
}
83+
84+
void iso14443_4_layer_set_s_block(Iso14443_4Layer* instance, bool deselect, bool CID_present) {
85+
furi_assert(instance);
86+
uint8_t des_wtx = !deselect ? (ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_MASK) : 0;
87+
instance->pcb = ISO14443_4_BLOCK_PCB_S_MASK | des_wtx |
88+
(CID_present << ISO14443_4_BLOCK_PCB_S_CID_OFFSET) | ISO14443_4_BLOCK_PCB;
89+
}
90+
3791
void iso14443_4_layer_encode_block(
3892
Iso14443_4Layer* instance,
3993
const BitBuffer* input_data,
@@ -46,6 +100,11 @@ void iso14443_4_layer_encode_block(
46100
iso14443_4_layer_update_pcb(instance);
47101
}
48102

103+
static inline uint8_t iso14443_4_layer_get_response_pcb(const BitBuffer* block_data) {
104+
const uint8_t* data = bit_buffer_get_data(block_data);
105+
return data[0];
106+
}
107+
49108
bool iso14443_4_layer_decode_block(
50109
Iso14443_4Layer* instance,
51110
BitBuffer* output_data,
@@ -55,9 +114,26 @@ bool iso14443_4_layer_decode_block(
55114
bool ret = false;
56115

57116
do {
58-
if(!bit_buffer_starts_with_byte(block_data, instance->pcb_prev)) break;
59-
bit_buffer_copy_right(output_data, block_data, 1);
60-
ret = true;
117+
if(ISO14443_4_BLOCK_PCB_IS_R_BLOCK(instance->pcb_prev)) {
118+
const uint8_t response_pcb = iso14443_4_layer_get_response_pcb(block_data);
119+
ret = (ISO14443_4_BLOCK_PCB_IS_R_BLOCK(response_pcb)) &&
120+
(!ISO14443_4_BLOCK_PCB_R_NACK_ACTIVE(response_pcb));
121+
instance->pcb &= ISO14443_4_BLOCK_PCB_MASK;
122+
iso14443_4_layer_update_pcb(instance);
123+
} else if(ISO14443_4_BLOCK_PCB_IS_CHAIN_ACTIVE(instance->pcb_prev)) {
124+
const uint8_t response_pcb = iso14443_4_layer_get_response_pcb(block_data);
125+
ret = (ISO14443_4_BLOCK_PCB_IS_R_BLOCK(response_pcb)) &&
126+
(!ISO14443_4_BLOCK_PCB_R_NACK_ACTIVE(response_pcb));
127+
instance->pcb &= ~(ISO14443_4_BLOCK_PCB_I_CHAIN_MASK);
128+
} else if(ISO14443_4_BLOCK_PCB_IS_S_BLOCK(instance->pcb_prev)) {
129+
ret = bit_buffer_starts_with_byte(block_data, instance->pcb_prev);
130+
if(bit_buffer_get_size_bytes(block_data) > 1)
131+
bit_buffer_copy_right(output_data, block_data, 1);
132+
} else {
133+
if(!bit_buffer_starts_with_byte(block_data, instance->pcb_prev)) break;
134+
bit_buffer_copy_right(output_data, block_data, 1);
135+
ret = true;
136+
}
61137
} while(false);
62138

63139
return ret;

lib/nfc/helpers/iso14443_4_layer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ void iso14443_4_layer_free(Iso14443_4Layer* instance);
1414

1515
void iso14443_4_layer_reset(Iso14443_4Layer* instance);
1616

17+
void iso14443_4_layer_set_i_block(Iso14443_4Layer* instance, bool chaining, bool CID_present);
18+
void iso14443_4_layer_set_r_block(Iso14443_4Layer* instance, bool acknowledged, bool CID_present);
19+
void iso14443_4_layer_set_s_block(Iso14443_4Layer* instance, bool deselect, bool CID_present);
20+
1721
void iso14443_4_layer_encode_block(
1822
Iso14443_4Layer* instance,
1923
const BitBuffer* input_data,

lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,8 @@ static NfcCommand iso14443_4a_listener_run(NfcGenericEvent event, void* context)
6565
if(instance->state == Iso14443_4aListenerStateIdle) {
6666
if(bit_buffer_get_size_bytes(rx_buffer) == 2 &&
6767
bit_buffer_get_byte(rx_buffer, 0) == ISO14443_4A_CMD_READ_ATS) {
68-
if(iso14443_4a_listener_send_ats(instance, &instance->data->ats_data) !=
68+
if(iso14443_4a_listener_send_ats(instance, &instance->data->ats_data) ==
6969
Iso14443_4aErrorNone) {
70-
command = NfcCommandContinue;
71-
} else {
7270
instance->state = Iso14443_4aListenerStateActive;
7371
}
7472
}
@@ -84,7 +82,15 @@ static NfcCommand iso14443_4a_listener_run(NfcGenericEvent event, void* context)
8482
iso14443_3a_event->type == Iso14443_3aListenerEventTypeHalted ||
8583
iso14443_3a_event->type == Iso14443_3aListenerEventTypeFieldOff) {
8684
instance->state = Iso14443_4aListenerStateIdle;
87-
command = NfcCommandContinue;
85+
86+
instance->iso14443_4a_event.type = iso14443_3a_event->type ==
87+
Iso14443_3aListenerEventTypeHalted ?
88+
Iso14443_4aListenerEventTypeHalted :
89+
Iso14443_4aListenerEventTypeFieldOff;
90+
91+
if(instance->callback) {
92+
command = instance->callback(instance->generic_event, instance->context);
93+
}
8894
}
8995

9096
return command;

lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ typedef struct Iso14443_4aListener Iso14443_4aListener;
1212

1313
typedef enum {
1414
Iso14443_4aListenerEventTypeHalted,
15+
Iso14443_4aListenerEventTypeFieldOff,
1516
Iso14443_4aListenerEventTypeReceivedData,
1617
} Iso14443_4aListenerEventType;
1718

lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,69 @@ Iso14443_4aError iso14443_4a_poller_send_block(
5656
const BitBuffer* tx_buffer,
5757
BitBuffer* rx_buffer);
5858

59+
/**
60+
* @brief Transmit and receive Iso14443_4a chained block in poller mode. Also it
61+
* automatically modifies PCB packet byte with appropriate bits then resets them back
62+
*
63+
* Must ONLY be used inside the callback function.
64+
*
65+
* The rx_buffer will be filled with any data received as a response to data
66+
* sent from tx_buffer. The fwt parameter is calculated during activation procedure.
67+
*
68+
* @param[in, out] instance pointer to the instance to be used in the transaction.
69+
* @param[in] tx_buffer pointer to the buffer containing the data to be transmitted.
70+
* @param[out] rx_buffer pointer to the buffer to be filled with received data.
71+
* @return Iso14443_4aErrorNone on success, an error code on failure.
72+
*/
73+
Iso14443_4aError iso14443_4a_poller_send_chain_block(
74+
Iso14443_4aPoller* instance,
75+
const BitBuffer* tx_buffer,
76+
BitBuffer* rx_buffer);
77+
78+
/**
79+
* @brief Transmit Iso14443_4a R-block in poller mode. This block never contains
80+
* data, but can contain CID and NAD, therefore in tx_buffer only two bytes can be added.
81+
* The first one will represent CID, the second one will represent NAD.
82+
*
83+
* Must ONLY be used inside the callback function.
84+
*
85+
* The rx_buffer will be filled with R-block repsonse
86+
*
87+
* @param[in, out] instance pointer to the instance to be used in the transaction.
88+
* @param[in] acknowledged Sets appropriate bit in PCB byte. True - ACK, false - NAK
89+
* @param[in] tx_buffer pointer to the buffer containing the data to be transmitted.
90+
* @param[out] rx_buffer pointer to the buffer to be filled with received data.
91+
* @return Iso14443_4aErrorNone on success, an error code on failure.
92+
*/
93+
Iso14443_4aError iso14443_4a_poller_send_receive_ready_block(
94+
Iso14443_4aPoller* instance,
95+
bool acknowledged,
96+
const BitBuffer* tx_buffer,
97+
BitBuffer* rx_buffer);
98+
99+
/**
100+
* @brief Transmit Iso14443_4a S-block in poller mode. S-block used to exchange control
101+
* information between the card and the reader. Two different types of S-blocks
102+
* are defined:
103+
* - Waiting time extension containing a 1 byte long INF field and (deselect = false)
104+
* - DESELECT containing no INF field (deselect = true)
105+
*
106+
* Must ONLY be used inside the callback function.
107+
*
108+
* The rx_buffer will be filled with R-block repsonse
109+
*
110+
* @param[in, out] instance pointer to the instance to be used in the transaction.
111+
* @param[in] deselect Sets appropriate bit in PCB byte.
112+
* @param[in] tx_buffer pointer to the buffer containing the data to be transmitted.
113+
* @param[out] rx_buffer pointer to the buffer to be filled with received data.
114+
* @return Iso14443_4aErrorNone on success, an error code on failure.
115+
*/
116+
Iso14443_4aError iso14443_4a_poller_send_supervisory_block(
117+
Iso14443_4aPoller* instance,
118+
bool deselect,
119+
const BitBuffer* tx_buffer,
120+
BitBuffer* rx_buffer);
121+
59122
/**
60123
* @brief Send HALT command to the card.
61124
*

lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,34 @@ Iso14443_4aError iso14443_4a_poller_send_block(
114114

115115
return error;
116116
}
117+
118+
Iso14443_4aError iso14443_4a_poller_send_chain_block(
119+
Iso14443_4aPoller* instance,
120+
const BitBuffer* tx_buffer,
121+
BitBuffer* rx_buffer) {
122+
iso14443_4_layer_set_i_block(instance->iso14443_4_layer, true, false);
123+
Iso14443_4aError error = iso14443_4a_poller_send_block(instance, tx_buffer, rx_buffer);
124+
return error;
125+
}
126+
127+
Iso14443_4aError iso14443_4a_poller_send_receive_ready_block(
128+
Iso14443_4aPoller* instance,
129+
bool acknowledged,
130+
const BitBuffer* tx_buffer,
131+
BitBuffer* rx_buffer) {
132+
bool CID_present = bit_buffer_get_size_bytes(tx_buffer) != 0;
133+
iso14443_4_layer_set_r_block(instance->iso14443_4_layer, acknowledged, CID_present);
134+
Iso14443_4aError error = iso14443_4a_poller_send_block(instance, tx_buffer, rx_buffer);
135+
return error;
136+
}
137+
138+
Iso14443_4aError iso14443_4a_poller_send_supervisory_block(
139+
Iso14443_4aPoller* instance,
140+
bool deselect,
141+
const BitBuffer* tx_buffer,
142+
BitBuffer* rx_buffer) {
143+
bool CID_present = bit_buffer_get_size_bytes(tx_buffer) != 0;
144+
iso14443_4_layer_set_s_block(instance->iso14443_4_layer, deselect, CID_present);
145+
Iso14443_4aError error = iso14443_4a_poller_send_block(instance, tx_buffer, rx_buffer);
146+
return error;
147+
}

targets/f18/api_symbols.csv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
entry,status,name,type,params
2-
Version,+,77.0,,
2+
Version,+,77.1,,
33
Header,+,applications/services/bt/bt_service/bt.h,,
44
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
55
Header,+,applications/services/cli/cli.h,,
@@ -746,6 +746,7 @@ Function,+,canvas_draw_str,void,"Canvas*, int32_t, int32_t, const char*"
746746
Function,+,canvas_draw_str_aligned,void,"Canvas*, int32_t, int32_t, Align, Align, const char*"
747747
Function,+,canvas_draw_triangle,void,"Canvas*, int32_t, int32_t, size_t, size_t, CanvasDirection"
748748
Function,+,canvas_draw_xbm,void,"Canvas*, int32_t, int32_t, size_t, size_t, const uint8_t*"
749+
Function,+,canvas_draw_xbm_ex,void,"Canvas*, int32_t, int32_t, size_t, size_t, IconRotation, const uint8_t*"
749750
Function,+,canvas_get_font_params,const CanvasFontParameters*,"const Canvas*, Font"
750751
Function,+,canvas_glyph_width,size_t,"Canvas*, uint16_t"
751752
Function,+,canvas_height,size_t,const Canvas*

0 commit comments

Comments
 (0)