Skip to content

Commit 06a58eb

Browse files
committed
Merge branch 'ofw_dev' into dev [ci skip]
2 parents 159aef0 + eb6fe0a commit 06a58eb

File tree

11 files changed

+486
-26
lines changed

11 files changed

+486
-26
lines changed

applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ enum {
1212
SubmenuIndexUnlock = SubmenuIndexCommonMax,
1313
SubmenuIndexUnlockByReader,
1414
SubmenuIndexUnlockByPassword,
15+
SubmenuIndexWrite,
1516
};
1617

1718
static void nfc_scene_info_on_enter_mf_ultralight(NfcApp* instance) {
@@ -106,6 +107,15 @@ static void nfc_scene_read_and_saved_menu_on_enter_mf_ultralight(NfcApp* instanc
106107
SubmenuIndexUnlock,
107108
nfc_protocol_support_common_submenu_callback,
108109
instance);
110+
} else if(
111+
data->type == MfUltralightTypeNTAG213 || data->type == MfUltralightTypeNTAG215 ||
112+
data->type == MfUltralightTypeNTAG216) {
113+
submenu_add_item(
114+
submenu,
115+
"Write",
116+
SubmenuIndexWrite,
117+
nfc_protocol_support_common_submenu_callback,
118+
instance);
109119
}
110120
}
111121

@@ -146,6 +156,9 @@ static bool
146156
if(event == SubmenuIndexUnlock) {
147157
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightUnlockMenu);
148158
return true;
159+
} else if(event == SubmenuIndexWrite) {
160+
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWrite);
161+
return true;
149162
}
150163
return false;
151164
}

applications/main/nfc/scenes/nfc_scene_config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ ADD_SCENE(nfc, field, Field)
2424
ADD_SCENE(nfc, retry_confirm, RetryConfirm)
2525
ADD_SCENE(nfc, exit_confirm, ExitConfirm)
2626

27+
ADD_SCENE(nfc, mf_ultralight_write, MfUltralightWrite)
28+
ADD_SCENE(nfc, mf_ultralight_write_success, MfUltralightWriteSuccess)
29+
ADD_SCENE(nfc, mf_ultralight_write_fail, MfUltralightWriteFail)
30+
ADD_SCENE(nfc, mf_ultralight_wrong_card, MfUltralightWrongCard)
2731
ADD_SCENE(nfc, mf_ultralight_unlock_menu, MfUltralightUnlockMenu)
2832
ADD_SCENE(nfc, mf_ultralight_unlock_warn, MfUltralightUnlockWarn)
2933
ADD_SCENE(nfc, mf_ultralight_key_input, MfUltralightKeyInput)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include "../nfc_app_i.h"
2+
3+
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller.h>
4+
5+
enum {
6+
NfcSceneMfUltralightWriteStateCardSearch,
7+
NfcSceneMfUltralightWriteStateCardFound,
8+
};
9+
10+
NfcCommand nfc_scene_mf_ultralight_write_worker_callback(NfcGenericEvent event, void* context) {
11+
furi_assert(context);
12+
furi_assert(event.event_data);
13+
furi_assert(event.protocol == NfcProtocolMfUltralight);
14+
15+
NfcCommand command = NfcCommandContinue;
16+
NfcApp* instance = context;
17+
MfUltralightPollerEvent* mfu_event = event.event_data;
18+
19+
if(mfu_event->type == MfUltralightPollerEventTypeRequestMode) {
20+
mfu_event->data->poller_mode = MfUltralightPollerModeWrite;
21+
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
22+
} else if(mfu_event->type == MfUltralightPollerEventTypeAuthRequest) {
23+
mfu_event->data->auth_context.skip_auth = true;
24+
} else if(mfu_event->type == MfUltralightPollerEventTypeRequestWriteData) {
25+
mfu_event->data->write_data =
26+
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
27+
} else if(mfu_event->type == MfUltralightPollerEventTypeCardMismatch) {
28+
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventWrongCard);
29+
command = NfcCommandStop;
30+
} else if(mfu_event->type == MfUltralightPollerEventTypeCardLocked) {
31+
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
32+
command = NfcCommandStop;
33+
} else if(mfu_event->type == MfUltralightPollerEventTypeWriteFail) {
34+
command = NfcCommandStop;
35+
} else if(mfu_event->type == MfUltralightPollerEventTypeWriteSuccess) {
36+
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
37+
command = NfcCommandStop;
38+
}
39+
return command;
40+
}
41+
42+
static void nfc_scene_mf_ultralight_write_setup_view(NfcApp* instance) {
43+
Popup* popup = instance->popup;
44+
popup_reset(popup);
45+
uint32_t state =
46+
scene_manager_get_scene_state(instance->scene_manager, NfcSceneMfUltralightWrite);
47+
48+
if(state == NfcSceneMfUltralightWriteStateCardSearch) {
49+
popup_set_text(
50+
instance->popup, "Apply the initial\ncard only", 128, 32, AlignRight, AlignCenter);
51+
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
52+
} else {
53+
popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter);
54+
popup_set_icon(popup, 12, 23, &A_Loading_24);
55+
}
56+
57+
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
58+
}
59+
60+
void nfc_scene_mf_ultralight_write_on_enter(void* context) {
61+
NfcApp* instance = context;
62+
dolphin_deed(DolphinDeedNfcEmulate);
63+
64+
scene_manager_set_scene_state(
65+
instance->scene_manager,
66+
NfcSceneMfUltralightWrite,
67+
NfcSceneMfUltralightWriteStateCardSearch);
68+
nfc_scene_mf_ultralight_write_setup_view(instance);
69+
70+
// Setup and start worker
71+
FURI_LOG_D("WMFU", "Card searching...");
72+
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfUltralight);
73+
nfc_poller_start(instance->poller, nfc_scene_mf_ultralight_write_worker_callback, instance);
74+
75+
nfc_blink_emulate_start(instance);
76+
}
77+
78+
bool nfc_scene_mf_ultralight_write_on_event(void* context, SceneManagerEvent event) {
79+
NfcApp* instance = context;
80+
bool consumed = false;
81+
82+
if(event.type == SceneManagerEventTypeCustom) {
83+
if(event.event == NfcCustomEventCardDetected) {
84+
scene_manager_set_scene_state(
85+
instance->scene_manager,
86+
NfcSceneMfUltralightWrite,
87+
NfcSceneMfUltralightWriteStateCardFound);
88+
nfc_scene_mf_ultralight_write_setup_view(instance);
89+
consumed = true;
90+
} else if(event.event == NfcCustomEventWrongCard) {
91+
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWrongCard);
92+
consumed = true;
93+
} else if(event.event == NfcCustomEventPollerSuccess) {
94+
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWriteSuccess);
95+
consumed = true;
96+
} else if(event.event == NfcCustomEventPollerFailure) {
97+
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWriteFail);
98+
consumed = true;
99+
}
100+
}
101+
102+
return consumed;
103+
}
104+
105+
void nfc_scene_mf_ultralight_write_on_exit(void* context) {
106+
NfcApp* instance = context;
107+
108+
nfc_poller_stop(instance->poller);
109+
nfc_poller_free(instance->poller);
110+
111+
scene_manager_set_scene_state(
112+
instance->scene_manager,
113+
NfcSceneMfUltralightWrite,
114+
NfcSceneMfUltralightWriteStateCardSearch);
115+
// Clear view
116+
popup_reset(instance->popup);
117+
118+
nfc_blink_stop(instance);
119+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include "../nfc_app_i.h"
2+
3+
void nfc_scene_mf_ultralight_write_fail_widget_callback(
4+
GuiButtonType result,
5+
InputType type,
6+
void* context) {
7+
NfcApp* instance = context;
8+
if(type == InputTypeShort) {
9+
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
10+
}
11+
}
12+
13+
void nfc_scene_mf_ultralight_write_fail_on_enter(void* context) {
14+
NfcApp* instance = context;
15+
Widget* widget = instance->widget;
16+
17+
notification_message(instance->notifications, &sequence_error);
18+
19+
widget_add_icon_element(widget, 72, 17, &I_DolphinCommon_56x48);
20+
widget_add_string_element(
21+
widget, 7, 4, AlignLeft, AlignTop, FontPrimary, "Writing gone wrong!");
22+
widget_add_string_multiline_element(
23+
widget,
24+
7,
25+
17,
26+
AlignLeft,
27+
AlignTop,
28+
FontSecondary,
29+
"Card protected by\npassword, AUTH0\nor lock bits");
30+
31+
widget_add_button_element(
32+
widget,
33+
GuiButtonTypeLeft,
34+
"Finish",
35+
nfc_scene_mf_ultralight_write_fail_widget_callback,
36+
instance);
37+
38+
// Setup and start worker
39+
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
40+
}
41+
42+
static bool nfc_scene_mf_ultralight_write_fail_move_to_back_scene(const NfcApp* const instance) {
43+
bool was_saved = scene_manager_has_previous_scene(instance->scene_manager, NfcSceneSavedMenu);
44+
uint32_t scene_id = was_saved ? NfcSceneSavedMenu : NfcSceneReadMenu;
45+
46+
return scene_manager_search_and_switch_to_previous_scene(instance->scene_manager, scene_id);
47+
}
48+
49+
bool nfc_scene_mf_ultralight_write_fail_on_event(void* context, SceneManagerEvent event) {
50+
NfcApp* instance = context;
51+
bool consumed = false;
52+
53+
if(event.type == SceneManagerEventTypeCustom) {
54+
if(event.event == GuiButtonTypeLeft) {
55+
consumed = nfc_scene_mf_ultralight_write_fail_move_to_back_scene(instance);
56+
}
57+
} else if(event.type == SceneManagerEventTypeBack) {
58+
consumed = nfc_scene_mf_ultralight_write_fail_move_to_back_scene(instance);
59+
}
60+
return consumed;
61+
}
62+
63+
void nfc_scene_mf_ultralight_write_fail_on_exit(void* context) {
64+
NfcApp* instance = context;
65+
66+
widget_reset(instance->widget);
67+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "../nfc_app_i.h"
2+
3+
void nfc_scene_mf_ultralight_write_success_popup_callback(void* context) {
4+
NfcApp* instance = context;
5+
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventViewExit);
6+
}
7+
8+
void nfc_scene_mf_ultralight_write_success_on_enter(void* context) {
9+
NfcApp* instance = context;
10+
dolphin_deed(DolphinDeedNfcSave);
11+
12+
notification_message(instance->notifications, &sequence_success);
13+
14+
Popup* popup = instance->popup;
15+
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
16+
popup_set_header(popup, "Successfully\nwritten", 13, 22, AlignLeft, AlignBottom);
17+
popup_set_timeout(popup, 1500);
18+
popup_set_context(popup, instance);
19+
popup_set_callback(popup, nfc_scene_mf_ultralight_write_success_popup_callback);
20+
popup_enable_timeout(popup);
21+
22+
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
23+
}
24+
25+
bool nfc_scene_mf_ultralight_write_success_on_event(void* context, SceneManagerEvent event) {
26+
NfcApp* instance = context;
27+
bool consumed = false;
28+
29+
if(event.type == SceneManagerEventTypeCustom) {
30+
if(event.event == NfcCustomEventViewExit) {
31+
consumed = scene_manager_search_and_switch_to_previous_scene(
32+
instance->scene_manager, NfcSceneSavedMenu);
33+
}
34+
}
35+
return consumed;
36+
}
37+
38+
void nfc_scene_mf_ultralight_write_success_on_exit(void* context) {
39+
NfcApp* instance = context;
40+
41+
// Clear view
42+
popup_reset(instance->popup);
43+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "../nfc_app_i.h"
2+
3+
void nfc_scene_mf_ultralight_wrong_card_widget_callback(
4+
GuiButtonType result,
5+
InputType type,
6+
void* context) {
7+
NfcApp* instance = context;
8+
if(type == InputTypeShort) {
9+
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
10+
}
11+
}
12+
13+
void nfc_scene_mf_ultralight_wrong_card_on_enter(void* context) {
14+
NfcApp* instance = context;
15+
Widget* widget = instance->widget;
16+
17+
notification_message(instance->notifications, &sequence_error);
18+
19+
widget_add_icon_element(widget, 73, 17, &I_DolphinCommon_56x48);
20+
widget_add_string_element(
21+
widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "This is wrong card");
22+
widget_add_string_multiline_element(
23+
widget,
24+
4,
25+
17,
26+
AlignLeft,
27+
AlignTop,
28+
FontSecondary,
29+
"Card of the same\ntype should be\n presented");
30+
//"Data management\nis only possible\nwith card of same type");
31+
widget_add_button_element(
32+
widget,
33+
GuiButtonTypeLeft,
34+
"Retry",
35+
nfc_scene_mf_ultralight_wrong_card_widget_callback,
36+
instance);
37+
38+
// Setup and start worker
39+
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
40+
}
41+
42+
bool nfc_scene_mf_ultralight_wrong_card_on_event(void* context, SceneManagerEvent event) {
43+
NfcApp* instance = context;
44+
bool consumed = false;
45+
46+
if(event.type == SceneManagerEventTypeCustom) {
47+
if(event.event == GuiButtonTypeLeft) {
48+
consumed = scene_manager_previous_scene(instance->scene_manager);
49+
}
50+
}
51+
return consumed;
52+
}
53+
54+
void nfc_scene_mf_ultralight_wrong_card_on_exit(void* context) {
55+
NfcApp* instance = context;
56+
57+
widget_reset(instance->widget);
58+
}

lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -108,28 +108,30 @@ Iso15693_3Error iso15693_3_poller_activate(Iso15693_3Poller* instance, Iso15693_
108108
break;
109109
}
110110

111-
// Read blocks: Optional command
112-
simple_array_init(data->block_data, system_info->block_count * system_info->block_size);
113-
ret = iso15693_3_poller_read_blocks(
114-
instance,
115-
simple_array_get_data(data->block_data),
116-
system_info->block_count,
117-
system_info->block_size);
118-
if(ret != Iso15693_3ErrorNone) {
119-
ret = iso15693_3_poller_filter_error(ret);
120-
break;
121-
}
122-
123-
// Get block security status: Optional command
124-
simple_array_init(data->block_security, system_info->block_count);
125-
126-
ret = iso15693_3_poller_get_blocks_security(
127-
instance, simple_array_get_data(data->block_security), system_info->block_count);
128-
if(ret != Iso15693_3ErrorNone) {
129-
ret = iso15693_3_poller_filter_error(ret);
130-
break;
111+
if(system_info->block_count > 0) {
112+
// Read blocks: Optional command
113+
simple_array_init(
114+
data->block_data, system_info->block_count * system_info->block_size);
115+
ret = iso15693_3_poller_read_blocks(
116+
instance,
117+
simple_array_get_data(data->block_data),
118+
system_info->block_count,
119+
system_info->block_size);
120+
if(ret != Iso15693_3ErrorNone) {
121+
ret = iso15693_3_poller_filter_error(ret);
122+
break;
123+
}
124+
125+
// Get block security status: Optional command
126+
simple_array_init(data->block_security, system_info->block_count);
127+
128+
ret = iso15693_3_poller_get_blocks_security(
129+
instance, simple_array_get_data(data->block_security), system_info->block_count);
130+
if(ret != Iso15693_3ErrorNone) {
131+
ret = iso15693_3_poller_filter_error(ret);
132+
break;
133+
}
131134
}
132-
133135
} while(false);
134136

135137
return ret;

0 commit comments

Comments
 (0)