Browse Source

Password via G-code and MarlinUI (#18399)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
sherwin-dc 3 years ago
parent
commit
852e5ae042
No account linked to committer's email address

+ 31
- 0
Marlin/Configuration.h View File

@@ -1642,6 +1642,37 @@
1642 1642
  */
1643 1643
 //#define PRINTCOUNTER
1644 1644
 
1645
+/**
1646
+ * Password
1647
+ *
1648
+ * Set a numerical password for the printer which can be requested:
1649
+ *
1650
+ *  - When the printer boots up
1651
+ *  - Upon opening the 'Print from Media' Menu
1652
+ *  - When SD printing is completed or aborted
1653
+ *
1654
+ * The following G-codes can be used:
1655
+ *
1656
+ *  M510 - Lock Printer. Blocks all commands except M511.
1657
+ *  M511 - Unlock Printer.
1658
+ *  M512 - Set, Change and Remove Password.
1659
+ *
1660
+ * If you forget the password and get locked out you'll need to re-flash
1661
+ * the firmware with the feature disabled, reset EEPROM, and (optionally)
1662
+ * re-flash the firmware again with this feature enabled.
1663
+ */
1664
+//#define PASSWORD_FEATURE
1665
+#if ENABLED(PASSWORD_FEATURE)
1666
+  #define PASSWORD_LENGTH 4                 // (#) Number of digits (1-9). 3 or 4 is recommended
1667
+  #define PASSWORD_ON_STARTUP
1668
+  #define PASSWORD_UNLOCK_GCODE             // Unlock with the M511 P<password> command. Disable to prevent brute-force attack.
1669
+  #define PASSWORD_CHANGE_GCODE             // Change the password with M512 P<old> N<new>.
1670
+  //#define PASSWORD_ON_SD_PRINT_MENU       // This does not prevent gcodes from running
1671
+  //#define PASSWORD_AFTER_SD_PRINT_END
1672
+  //#define PASSWORD_AFTER_SD_PRINT_ABORT
1673
+  //#include "Configuration_Secure.h"       // External file with PASSWORD_DEFAULT_VALUE
1674
+#endif
1675
+
1645 1676
 //=============================================================================
1646 1677
 //============================= LCD and SD support ============================
1647 1678
 //=============================================================================

+ 13
- 1
Marlin/src/MarlinCore.cpp View File

@@ -213,6 +213,10 @@
213 213
   #include "libs/L64XX/L64XX_Marlin.h"
214 214
 #endif
215 215
 
216
+#if ENABLED(PASSWORD_FEATURE)
217
+  #include "feature/password/password.h"
218
+#endif
219
+
216 220
 PGMSTR(NUL_STR, "");
217 221
 PGMSTR(M112_KILL_STR, "M112 Shutdown");
218 222
 PGMSTR(G28_STR, "G28");
@@ -452,11 +456,15 @@ void startOrResumeJob() {
452 456
     #ifdef EVENT_GCODE_SD_STOP
453 457
       queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
454 458
     #endif
459
+
460
+    TERN_(PASSWORD_AFTER_SD_PRINT_ABORT, password.lock_machine());
455 461
   }
456 462
 
457 463
   inline void finishSDPrinting() {
458
-    if (queue.enqueue_one_P(PSTR("M1001")))
464
+    if (queue.enqueue_one_P(PSTR("M1001"))) {
459 465
       marlin_state = MF_RUNNING;
466
+      TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine());
467
+    }
460 468
   }
461 469
 
462 470
 #endif // SDSUPPORT
@@ -1205,6 +1213,10 @@ void setup() {
1205 1213
     SETUP_RUN(tft_lvgl_init());
1206 1214
   #endif
1207 1215
 
1216
+  #if ENABLED(PASSWORD_ON_STARTUP)
1217
+    SETUP_RUN(password.lock_machine());      // Will not proceed until correct password provided
1218
+  #endif
1219
+
1208 1220
   marlin_state = MF_RUNNING;
1209 1221
 
1210 1222
   SETUP_LOG("setup() completed.");

+ 7
- 0
Marlin/src/core/language.h View File

@@ -266,6 +266,13 @@
266 266
 #define STR_DEBUG_COMMUNICATION             "COMMUNICATION"
267 267
 #define STR_DEBUG_LEVELING                  "LEVELING"
268 268
 
269
+#define STR_PRINTER_LOCKED                  "Printer locked! (Unlock with M511 or LCD)"
270
+#define STR_WRONG_PASSWORD                  "Incorrect Password"
271
+#define STR_PASSWORD_TOO_LONG               "Password too long"
272
+#define STR_PASSWORD_REMOVED                "Password removed"
273
+#define STR_REMINDER_SAVE_SETTINGS          "Remember to save!"
274
+#define STR_PASSWORD_SET                    "Password is "
275
+
269 276
 // LCD Menu Messages
270 277
 
271 278
 #define LANGUAGE_DATA_INCL_(M) STRINGIFY_(fontdata/langdata_##M.h)

+ 32
- 19
Marlin/src/core/macros.h View File

@@ -342,15 +342,22 @@
342 342
 #endif
343 343
 
344 344
 // Macros for adding
345
-#define INC_0 1
346
-#define INC_1 2
347
-#define INC_2 3
348
-#define INC_3 4
349
-#define INC_4 5
350
-#define INC_5 6
351
-#define INC_6 7
352
-#define INC_7 8
353
-#define INC_8 9
345
+#define INC_0   1
346
+#define INC_1   2
347
+#define INC_2   3
348
+#define INC_3   4
349
+#define INC_4   5
350
+#define INC_5   6
351
+#define INC_6   7
352
+#define INC_7   8
353
+#define INC_8   9
354
+#define INC_9  10
355
+#define INC_10 11
356
+#define INC_11 12
357
+#define INC_12 13
358
+#define INC_13 14
359
+#define INC_14 15
360
+#define INC_15 16
354 361
 #define INCREMENT_(n) INC_##n
355 362
 #define INCREMENT(n) INCREMENT_(n)
356 363
 
@@ -367,16 +374,22 @@
367 374
 #define ADD10(N) ADD5(ADD5(N))
368 375
 
369 376
 // Macros for subtracting
370
-#define DEC_0 0
371
-#define DEC_1 0
372
-#define DEC_2 1
373
-#define DEC_3 2
374
-#define DEC_4 3
375
-#define DEC_5 4
376
-#define DEC_6 5
377
-#define DEC_7 6
378
-#define DEC_8 7
379
-#define DEC_9 8
377
+#define DEC_0   0
378
+#define DEC_1   0
379
+#define DEC_2   1
380
+#define DEC_3   2
381
+#define DEC_4   3
382
+#define DEC_5   4
383
+#define DEC_6   5
384
+#define DEC_7   6
385
+#define DEC_8   7
386
+#define DEC_9   8
387
+#define DEC_10  9
388
+#define DEC_11 10
389
+#define DEC_12 11
390
+#define DEC_13 12
391
+#define DEC_14 13
392
+#define DEC_15 14
380 393
 #define DECREMENT_(n) DEC_##n
381 394
 #define DECREMENT(n) DECREMENT_(n)
382 395
 

+ 58
- 0
Marlin/src/feature/password/password.cpp View File

@@ -0,0 +1,58 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../inc/MarlinConfigPre.h"
24
+
25
+#if ENABLED(PASSWORD_FEATURE)
26
+
27
+#include "password.h"
28
+#include "../../gcode/gcode.h"
29
+#include "../../core/serial.h"
30
+
31
+Password password;
32
+
33
+// public:
34
+bool     Password::is_set, Password::is_locked;
35
+uint32_t Password::value, Password::value_entry;
36
+
37
+//
38
+// Authenticate user with password.
39
+// Called from Setup, after SD Prinitng Stops/Aborts, and M510
40
+//
41
+void Password::lock_machine() {
42
+  is_locked = true;
43
+  TERN_(HAS_LCD_MENU, authenticate_user(ui.status_screen, screen_password_entry));
44
+}
45
+
46
+//
47
+// Authentication check
48
+//
49
+void Password::authentication_check() {
50
+  if (value_entry == value)
51
+    is_locked = false;
52
+  else
53
+    SERIAL_ECHOLNPGM(STR_WRONG_PASSWORD);
54
+
55
+  TERN_(HAS_LCD_MENU, authentication_done());
56
+}
57
+
58
+#endif // PASSWORD_FEATURE

+ 57
- 0
Marlin/src/feature/password/password.h View File

@@ -0,0 +1,57 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+#pragma once
23
+
24
+#include "../../lcd/ultralcd.h"
25
+
26
+class Password {
27
+public:
28
+  static bool is_set, is_locked;
29
+  static uint32_t value, value_entry;
30
+
31
+  Password() { is_locked = false; }
32
+
33
+  static void lock_machine();
34
+
35
+  #if HAS_LCD_MENU
36
+    static void access_menu_password();
37
+    static void authentication_check();
38
+    static void authentication_done();
39
+    static void media_gatekeeper();
40
+
41
+    private:
42
+    static void authenticate_user(const screenFunc_t, const screenFunc_t);
43
+    static void menu_password();
44
+    static void menu_password_entry();
45
+    static void screen_password_entry();
46
+    static void screen_set_password();
47
+    static void start_over();
48
+
49
+    static void digit_entered();
50
+    static void set_password_done();
51
+    static void menu_password_report();
52
+
53
+    static void remove_password();
54
+  #endif
55
+};
56
+
57
+extern Password password;

+ 83
- 0
Marlin/src/gcode/feature/password/M510-M512.cpp View File

@@ -0,0 +1,83 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../../inc/MarlinConfigPre.h"
24
+
25
+#if ENABLED(PASSWORD_FEATURE)
26
+
27
+#include "../../../feature/password/password.h"
28
+#include "../../../core/serial.h"
29
+#include "../../gcode.h"
30
+
31
+//
32
+// M510: Lock Printer
33
+//
34
+void GcodeSuite::M510() {
35
+  password.lock_machine();
36
+}
37
+
38
+//
39
+// M511: Unlock Printer
40
+//
41
+#if ENABLED(PASSWORD_UNLOCK_GCODE)
42
+
43
+  void GcodeSuite::M511() {
44
+    if (password.is_locked) {
45
+      password.value_entry = parser.ulongval('P');
46
+      password.authentication_check();
47
+    }
48
+  }
49
+
50
+#endif // PASSWORD_UNLOCK_GCODE
51
+
52
+//
53
+// M512: Set/Change/Remove Password
54
+//
55
+#if ENABLED(PASSWORD_CHANGE_GCODE)
56
+
57
+  void GcodeSuite::M512() {
58
+    if (password.is_set && parser.ulongval('P') != password.value) {
59
+      SERIAL_ECHOLNPGM(STR_WRONG_PASSWORD);
60
+      return;
61
+     }
62
+
63
+    if (parser.seenval('N')) {
64
+      password.value_entry = parser.ulongval('N');
65
+
66
+      if (password.value_entry < CAT(1e, PASSWORD_LENGTH)) {
67
+        password.is_set = true;
68
+        password.value = password.value_entry;
69
+        SERIAL_ECHOLNPAIR(STR_PASSWORD_SET, password.value); // TODO: Update password.string
70
+      }
71
+      else
72
+        SERIAL_ECHOLNPGM(STR_PASSWORD_TOO_LONG);
73
+    }
74
+    else {
75
+      password.is_set = false;
76
+      SERIAL_ECHOLNPGM(STR_PASSWORD_REMOVED);
77
+    }
78
+    SERIAL_ECHOLNPGM(STR_REMINDER_SAVE_SETTINGS);
79
+  }
80
+
81
+#endif // PASSWORD_CHANGE_GCODE
82
+
83
+#endif // PASSWORD_FEATURE

+ 25
- 0
Marlin/src/gcode/gcode.cpp View File

@@ -57,6 +57,10 @@ GcodeSuite gcode;
57 57
   #include "../feature/spindle_laser.h"
58 58
 #endif
59 59
 
60
+#if ENABLED(PASSWORD_FEATURE)
61
+  #include "../feature/password/password.h"
62
+#endif
63
+
60 64
 #include "../MarlinCore.h" // for idle()
61 65
 
62 66
 // Inactivity shutdown
@@ -241,6 +245,17 @@ void GcodeSuite::dwell(millis_t time) {
241 245
 void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
242 246
   KEEPALIVE_STATE(IN_HANDLER);
243 247
 
248
+ /**
249
+  * Block all Gcodes except M511 Unlock Printer, if printer is locked
250
+  * Will still block Gcodes if M511 is disabled, in which case the printer should be unlocked via LCD Menu
251
+  */
252
+  #if ENABLED(PASSWORD_FEATURE)
253
+    if (password.is_locked && !(parser.command_letter == 'M' && parser.codenum == 511)) {
254
+      SERIAL_ECHO_MSG(STR_PRINTER_LOCKED);
255
+      return;
256
+    }
257
+  #endif
258
+
244 259
   // Handle a known G, M, or T
245 260
   switch (parser.command_letter) {
246 261
     case 'G': switch (parser.codenum) {
@@ -736,6 +751,16 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
736 751
         case 504: M504(); break;                                  // M504: Validate EEPROM contents
737 752
       #endif
738 753
 
754
+      #if ENABLED(PASSWORD_FEATURE)
755
+        case 510: M510(); break;                                  // M510: Lock Printer
756
+        #if ENABLED(PASSWORD_UNLOCK_GCODE)
757
+          case 511: M511(); break;                                // M511: Unlock Printer
758
+        #endif
759
+        #if ENABLED(PASSWORD_CHANGE_GCODE)
760
+          case 512: M512(); break;
761
+        #endif                                                    // M512: Set/Change/Remove Password
762
+      #endif
763
+
739 764
       #if ENABLED(SDSUPPORT)
740 765
         case 524: M524(); break;                                  // M524: Abort the current SD print job
741 766
       #endif

+ 13
- 0
Marlin/src/gcode/gcode.h View File

@@ -225,6 +225,9 @@
225 225
  * M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
226 226
  * M503 - Print the current settings (in memory): "M503 S<verbose>". S0 specifies compact output.
227 227
  * M504 - Validate EEPROM contents. (Requires EEPROM_SETTINGS)
228
+ * M510 - Lock Printer
229
+ * M511 - Unlock Printer
230
+ * M512 - Set/Change/Remove Password
228 231
  * M524 - Abort the current SD print job started with M24. (Requires SDSUPPORT)
229 232
  * M540 - Enable/disable SD card abort on endstop hit: "M540 S<state>". (Requires SD_ABORT_ON_ENDSTOP_HIT)
230 233
  * M569 - Enable stealthChop on an axis. (Requires at least one _DRIVER_TYPE to be TMC2130/2160/2208/2209/5130/5160)
@@ -760,6 +763,16 @@ private:
760 763
   #endif
761 764
   TERN_(EEPROM_SETTINGS, static void M504());
762 765
 
766
+  #if ENABLED(PASSWORD_FEATURE)
767
+    static void M510();
768
+    #if ENABLED(PASSWORD_UNLOCK_GCODE)
769
+      static void M511();
770
+    #endif
771
+    #if ENABLED(PASSWORD_CHANGE_GCODE)
772
+      static void M512();
773
+    #endif
774
+  #endif
775
+
763 776
   TERN_(SDSUPPORT, static void M524());
764 777
 
765 778
   TERN_(SD_ABORT_ON_ENDSTOP_HIT, static void M540());

+ 11
- 0
Marlin/src/inc/SanityCheck.h View File

@@ -3083,5 +3083,16 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
3083 3083
   #error "ESP3D_WIFISUPPORT or WIFISUPPORT requires an ESP32 controller."
3084 3084
 #endif
3085 3085
 
3086
+/**
3087
+ * Sanity Check for Password Feature
3088
+ */
3089
+#if ENABLED(PASSWORD_FEATURE)
3090
+  #if NONE(HAS_LCD_MENU, PASSWORD_UNLOCK_GCODE, PASSWORD_CHANGE_GCODE)
3091
+    #error "Without PASSWORD_UNLOCK_GCODE, PASSWORD_CHANGE_GCODE, or a supported LCD there's no way to unlock the printer or set a password."
3092
+  #elif DISABLED(EEPROM_SETTINGS)
3093
+    #warning "PASSWORD_FEATURE settings will be lost on power-off without EEPROM_SETTINGS."
3094
+  #endif
3095
+#endif
3096
+
3086 3097
 // Misc. Cleanup
3087 3098
 #undef _TEST_PWM

+ 11
- 0
Marlin/src/lcd/language/language_en.h View File

@@ -588,6 +588,17 @@ namespace Language_en {
588 588
   PROGMEM Language_Str MSG_BAD_PAGE                        = _UxGT("Bad page index");
589 589
   PROGMEM Language_Str MSG_BAD_PAGE_SPEED                  = _UxGT("Bad page speed");
590 590
 
591
+  PROGMEM Language_Str MSG_EDIT_PASSWORD                   = _UxGT("Edit Password");
592
+  PROGMEM Language_Str MSG_LOGIN_REQUIRED                  = _UxGT("Login Required");
593
+  PROGMEM Language_Str MSG_PASSWORD_SETTINGS               = _UxGT("Password Settings");
594
+  PROGMEM Language_Str MSG_ENTER_DIGIT                     = _UxGT("Enter Digit");
595
+  PROGMEM Language_Str MSG_CHANGE_PASSWORD                 = _UxGT("Set/Edit Password");
596
+  PROGMEM Language_Str MSG_REMOVE_PASSWORD                 = _UxGT("Remove Password");
597
+  PROGMEM Language_Str MSG_PASSWORD_SET                    = _UxGT("Password is ");
598
+  PROGMEM Language_Str MSG_START_OVER                      = _UxGT("Start Over");
599
+  PROGMEM Language_Str MSG_REMINDER_SAVE_SETTINGS          = _UxGT("Remember to Save!");
600
+  PROGMEM Language_Str MSG_PASSWORD_REMOVED                = _UxGT("Password Removed");
601
+
591 602
   //
592 603
   // Filament Change screens show up to 3 lines on a 4-line display
593 604
   //                        ...or up to 2 lines on a 3-line display

+ 8
- 0
Marlin/src/lcd/menu/menu_advanced.cpp View File

@@ -51,6 +51,10 @@
51 51
   #include "../../module/settings.h"
52 52
 #endif
53 53
 
54
+#if ENABLED(PASSWORD_FEATURE)
55
+  #include "../../feature/password/password.h"
56
+#endif
57
+
54 58
 void menu_tmc();
55 59
 void menu_backlash();
56 60
 
@@ -603,6 +607,10 @@ void menu_advanced_settings() {
603 607
     });
604 608
   #endif
605 609
 
610
+  #if ENABLED(PASSWORD_FEATURE)
611
+    SUBMENU(MSG_PASSWORD_SETTINGS, password.access_menu_password);
612
+  #endif
613
+
606 614
   #if ENABLED(EEPROM_SETTINGS) && DISABLED(SLIM_LCD_MENUS)
607 615
     CONFIRM_ITEM(MSG_INIT_EEPROM,
608 616
       MSG_BUTTON_INIT, MSG_BUTTON_CANCEL,

+ 6
- 2
Marlin/src/lcd/menu/menu_main.cpp View File

@@ -50,6 +50,10 @@
50 50
   #include "../../lcd/menu/menu_mmu2.h"
51 51
 #endif
52 52
 
53
+#if ENABLED(PASSWORD_FEATURE)
54
+  #include "../../feature/password/password.h"
55
+#endif
56
+
53 57
 void menu_tune();
54 58
 void menu_cancelobject();
55 59
 void menu_motion();
@@ -133,7 +137,7 @@ void menu_main() {
133 137
 
134 138
       if (card_detected) {
135 139
         if (!card_open) {
136
-          SUBMENU(MSG_MEDIA_MENU, menu_media);
140
+          SUBMENU(MSG_MEDIA_MENU, TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media));
137 141
           MENU_ITEM(gcode,
138 142
             #if PIN_EXISTS(SD_DETECT)
139 143
               MSG_CHANGE_MEDIA, M21_STR
@@ -240,7 +244,7 @@ void menu_main() {
240 244
               MSG_RELEASE_MEDIA, PSTR("M22")
241 245
             #endif
242 246
           );
243
-          SUBMENU(MSG_MEDIA_MENU, menu_media);
247
+          SUBMENU(MSG_MEDIA_MENU, TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media));
244 248
         }
245 249
       }
246 250
       else {

+ 184
- 0
Marlin/src/lcd/menu/menu_password.cpp View File

@@ -0,0 +1,184 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+//
24
+// Advanced Settings Menus
25
+//
26
+
27
+#include "../../inc/MarlinConfigPre.h"
28
+
29
+#if BOTH(HAS_LCD_MENU, PASSWORD_FEATURE)
30
+
31
+#include "../../feature/password/password.h"
32
+
33
+#include "menu.h"
34
+#include "menu_addon.h"
35
+
36
+void menu_advanced_settings();
37
+
38
+screenFunc_t success_screen, fail_screen;
39
+bool authenticating; // = false
40
+char string[(PASSWORD_LENGTH) + 1];
41
+static uint8_t digit_no;
42
+
43
+//
44
+// Screen for both editing and setting the password
45
+//
46
+void Password::menu_password_entry() {
47
+  START_MENU();
48
+
49
+  // "Login" or "New Code"
50
+  STATIC_ITEM_P(authenticating ? GET_TEXT(MSG_LOGIN_REQUIRED) : GET_TEXT(MSG_EDIT_PASSWORD), SS_CENTER|SS_INVERT);
51
+
52
+  STATIC_ITEM_P(PSTR(""), SS_CENTER|SS_INVERT, string);
53
+
54
+  // Make the digit edit item look like a sub-menu
55
+  PGM_P const label = GET_TEXT(MSG_ENTER_DIGIT);
56
+  EDIT_ITEM_P(uint8, label, &editable.uint8, 0, 9, digit_entered);
57
+  MENU_ITEM_ADDON_START(utf8_strlen_P(label) + 1);
58
+    lcd_put_wchar(' ');
59
+    lcd_put_wchar('1' + digit_no);
60
+    SETCURSOR_X(LCD_WIDTH - 1);
61
+    lcd_put_wchar('>');
62
+  MENU_ITEM_ADDON_END();
63
+
64
+  ACTION_ITEM(MSG_START_OVER, start_over);
65
+
66
+  if (!authenticating) BACK_ITEM(MSG_BUTTON_CANCEL);
67
+
68
+  END_MENU();
69
+}
70
+
71
+//
72
+// Authentication check
73
+//
74
+void Password::authentication_done() {
75
+  ui.goto_screen(is_locked ? fail_screen : success_screen);
76
+  ui.completion_feedback(!is_locked);
77
+}
78
+
79
+// A single digit was completed
80
+void Password::digit_entered() {
81
+  uint32_t multiplier = CAT(1e, PASSWORD_LENGTH); // 1e5 = 100000
82
+  LOOP_LE_N(i, digit_no) multiplier /= 10;
83
+  value_entry += editable.uint8 * multiplier;
84
+  string[digit_no++] = '0' + editable.uint8;
85
+
86
+  // Exit edit screen menu and go to another screen
87
+  ui.goto_previous_screen();
88
+  ui.use_click();
89
+  ui.goto_screen(menu_password_entry);
90
+
91
+  // After password has been keyed in
92
+  if (digit_no == PASSWORD_LENGTH) {
93
+    if (authenticating)
94
+      authentication_check();
95
+    else
96
+      set_password_done();
97
+  }
98
+}
99
+
100
+//
101
+// Set/Change Password
102
+//
103
+void Password::screen_password_entry() {
104
+  value_entry = 0;
105
+  digit_no = 0;
106
+  editable.uint8 = 0;
107
+  memset(string, '-', PASSWORD_LENGTH);
108
+  string[PASSWORD_LENGTH] = '\0';
109
+  menu_password_entry();
110
+}
111
+
112
+void Password::screen_set_password() {
113
+  authenticating = false;
114
+  screen_password_entry();
115
+}
116
+
117
+void Password::authenticate_user(const screenFunc_t in_succ_scr, const screenFunc_t in_fail_scr) {
118
+  success_screen = in_succ_scr;
119
+  fail_screen = in_fail_scr;
120
+  if (is_set) {
121
+    authenticating = true;
122
+    ui.goto_screen(screen_password_entry);
123
+    ui.defer_status_screen();
124
+    ui.update();
125
+  }
126
+  else {
127
+    ui.goto_screen(in_succ_scr);
128
+    is_locked = false;
129
+  }
130
+}
131
+
132
+void Password::access_menu_password() {
133
+  authenticate_user(menu_password, menu_advanced_settings);
134
+}
135
+
136
+#if ENABLED(PASSWORD_ON_SD_PRINT_MENU)
137
+  void Password::media_gatekeeper() {
138
+    authenticate_user(menu_media, menu_main);
139
+  }
140
+#endif
141
+
142
+void Password::start_over() {
143
+  ui.goto_previous_screen(); // Goto previous screen, if any
144
+  ui.goto_screen(screen_password_entry);
145
+}
146
+
147
+void Password::menu_password_report() {
148
+  START_SCREEN();
149
+  BACK_ITEM(MSG_PASSWORD_SETTINGS);
150
+  STATIC_ITEM(MSG_PASSWORD_SET, SS_LEFT, string);
151
+  STATIC_ITEM(MSG_REMINDER_SAVE_SETTINGS, SS_LEFT);
152
+  END_SCREEN();
153
+}
154
+
155
+void Password::set_password_done() {
156
+  is_set = true;
157
+  value = value_entry;
158
+  ui.completion_feedback(true);
159
+  ui.goto_screen(menu_password_report);
160
+}
161
+
162
+void Password::remove_password() {
163
+  is_set = false;
164
+  string[0] = '0';
165
+  string[1] = '\0';
166
+  ui.completion_feedback(true);
167
+  ui.goto_screen(menu_password_report);
168
+}
169
+
170
+//
171
+// Password Menu
172
+//
173
+void Password::menu_password() {
174
+  START_MENU();
175
+  BACK_ITEM(MSG_ADVANCED_SETTINGS);
176
+  SUBMENU(MSG_CHANGE_PASSWORD, screen_set_password);
177
+  ACTION_ITEM(MSG_REMOVE_PASSWORD, []{ ui.save_previous_screen(); remove_password(); } );
178
+  #if ENABLED(EEPROM_SETTINGS)
179
+    ACTION_ITEM(MSG_STORE_EEPROM, ui.store_settings);
180
+  #endif
181
+  END_MENU();
182
+}
183
+
184
+#endif // HAS_LCD_MENU && PASSWORD_FEATURE

+ 40
- 2
Marlin/src/module/settings.cpp View File

@@ -140,6 +140,10 @@
140 140
   #define HAS_CASE_LIGHT_BRIGHTNESS 1
141 141
 #endif
142 142
 
143
+#if ENABLED(PASSWORD_FEATURE)
144
+  #include "../feature/password/password.h"
145
+#endif
146
+
143 147
 #if ENABLED(TOUCH_SCREEN_CALIBRATION)
144 148
   #include "../lcd/tft/touch.h"
145 149
 #endif
@@ -152,7 +156,7 @@ typedef struct {  int16_t X, Y, Z, X2, Y2, Z2, Z3, Z4;
152 156
 typedef struct {     bool X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_stealth_enabled_t;
153 157
 
154 158
 // Limit an index to an array size
155
-#define ALIM(I,ARR) _MIN(I, signed(COUNT(ARR) - 1))
159
+#define ALIM(I,ARR) _MIN(I, (signed)COUNT(ARR) - 1)
156 160
 
157 161
 // Defaults for reset / fill in on load
158 162
 static const uint32_t   _DMA[] PROGMEM = DEFAULT_MAX_ACCELERATION;
@@ -408,6 +412,14 @@ typedef struct SettingsDataStruct {
408 412
   #endif
409 413
 
410 414
   //
415
+  // PASSWORD_FEATURE
416
+  //
417
+  #if ENABLED(PASSWORD_FEATURE)
418
+    bool password_is_set;
419
+    uint32_t password_value;
420
+  #endif
421
+
422
+  //
411 423
   // TOUCH_SCREEN_CALIBRATION
412 424
   //
413 425
   #if ENABLED(TOUCH_SCREEN_CALIBRATION)
@@ -1346,6 +1358,14 @@ void MarlinSettings::postprocess() {
1346 1358
     #endif
1347 1359
 
1348 1360
     //
1361
+    // Password feature
1362
+    //
1363
+    #if ENABLED(PASSWORD_FEATURE)
1364
+      EEPROM_WRITE(password.is_set);
1365
+      EEPROM_WRITE(password.value);
1366
+    #endif
1367
+
1368
+    //
1349 1369
     // TOUCH_SCREEN_CALIBRATION
1350 1370
     //
1351 1371
     #if ENABLED(TOUCH_SCREEN_CALIBRATION)
@@ -2186,6 +2206,15 @@ void MarlinSettings::postprocess() {
2186 2206
       #endif
2187 2207
 
2188 2208
       //
2209
+      // Password feature
2210
+      //
2211
+      #if ENABLED(PASSWORD_FEATURE)
2212
+        _FIELD_TEST(password_is_set);
2213
+        EEPROM_READ(password.is_set);
2214
+        EEPROM_READ(password.value);
2215
+      #endif
2216
+
2217
+      //
2189 2218
       // TOUCH_SCREEN_CALIBRATION
2190 2219
       //
2191 2220
       #if ENABLED(TOUCH_SCREEN_CALIBRATION)
@@ -2665,7 +2694,7 @@ void MarlinSettings::reset() {
2665 2694
       #define PID_DEFAULT(N,E) DEFAULT_##N
2666 2695
     #endif
2667 2696
     HOTEND_LOOP() {
2668
-      PID_PARAM(Kp, e) = float(PID_DEFAULT(Kp, ALIM(e, defKp)));
2697
+      PID_PARAM(Kp, e) =      float(PID_DEFAULT(Kp, ALIM(e, defKp)));
2669 2698
       PID_PARAM(Ki, e) = scalePID_i(PID_DEFAULT(Ki, ALIM(e, defKi)));
2670 2699
       PID_PARAM(Kd, e) = scalePID_d(PID_DEFAULT(Kd, ALIM(e, defKd)));
2671 2700
       TERN_(PID_EXTRUSION_SCALING, PID_PARAM(Kc, e) = float(PID_DEFAULT(Kc, ALIM(e, defKc))));
@@ -2783,6 +2812,15 @@ void MarlinSettings::reset() {
2783 2812
     }
2784 2813
   #endif
2785 2814
 
2815
+  #if ENABLED(PASSWORD_FEATURE)
2816
+    #ifdef PASSWORD_DEFAULT_VALUE
2817
+      password.is_set = true;
2818
+      password.value = PASSWORD_DEFAULT_VALUE;
2819
+    #else
2820
+      password.is_set = false;
2821
+    #endif
2822
+  #endif
2823
+
2786 2824
   postprocess();
2787 2825
 
2788 2826
   DEBUG_ECHO_START();

+ 3
- 0
buildroot/share/PlatformIO/scripts/common-dependencies.h View File

@@ -143,6 +143,9 @@
143 143
   #if ENABLED(MMU2_MENUS)
144 144
     #define HAS_MENU_MMU2
145 145
   #endif
146
+  #if ENABLED(PASSWORD_FEATURE)
147
+    #define HAS_MENU_PASSWORD
148
+  #endif
146 149
   #if HAS_TRINAMIC_CONFIG
147 150
     #define HAS_MENU_TMC
148 151
   #endif

+ 1
- 1
buildroot/tests/DUE-tests View File

@@ -33,7 +33,7 @@ opt_set EXTRUDER_AUTO_FAN_SPEED 100
33 33
 opt_set TEMP_SENSOR_CHAMBER 3
34 34
 opt_add TEMP_CHAMBER_PIN 6
35 35
 opt_set HEATER_CHAMBER_PIN 45
36
-exec_test $1 $2 "RAMPS4DUE_EFB with ABL (Bilinear), EXTENSIBLE_UI, S-Curve, many options."
36
+exec_test $1 $2 "RAMPS4DUE_EFB with ABL (Bilinear), ExtUI, S-Curve, many options."
37 37
 
38 38
 restore_configs
39 39
 opt_set MOTHERBOARD BOARD_RADDS

+ 1
- 0
buildroot/tests/rambo-tests View File

@@ -33,6 +33,7 @@ opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TE
33 33
            PRINTCOUNTER SERVICE_NAME_1 SERVICE_INTERVAL_1 LEVEL_BED_CORNERS \
34 34
            NOZZLE_PARK_FEATURE FILAMENT_RUNOUT_SENSOR FILAMENT_RUNOUT_DISTANCE_MM \
35 35
            ADVANCED_PAUSE_FEATURE FILAMENT_LOAD_UNLOAD_GCODES FILAMENT_UNLOAD_ALL_EXTRUDERS \
36
+           PASSWORD_FEATURE PASSWORD_ON_STARTUP PASSWORD_ON_SD_PRINT_MENU PASSWORD_AFTER_SD_PRINT_END PASSWORD_AFTER_SD_PRINT_ABORT \
36 37
            AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DISTINCT_E_FACTORS \
37 38
            SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \
38 39
            BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \

+ 4
- 0
platformio.ini View File

@@ -41,6 +41,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
41 41
   -<src/lcd/menu/menu_led.cpp>
42 42
   -<src/lcd/menu/menu_media.cpp>
43 43
   -<src/lcd/menu/menu_mmu2.cpp>
44
+  -<src/lcd/menu/menu_password.cpp>
44 45
   -<src/lcd/menu/menu_power_monitor.cpp>
45 46
   -<src/lcd/menu/menu_spindle_laser.cpp>
46 47
   -<src/lcd/menu/menu_temperature.cpp>
@@ -86,6 +87,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
86 87
   -<src/feature/max7219.cpp>
87 88
   -<src/feature/mixing.cpp>
88 89
   -<src/feature/mmu2> -<src/gcode/feature/prusa_MMU2>
90
+  -<src/feature/password> -<src/gcode/feature/password>
89 91
   -<src/feature/pause.cpp>
90 92
   -<src/feature/power.cpp>
91 93
   -<src/feature/power_monitor.cpp> -<src/gcode/feature/power_monitor>
@@ -231,6 +233,7 @@ HAS_MENU_LED            = src_filter=+<src/lcd/menu/menu_led.cpp>
231 233
 HAS_MENU_MEDIA          = src_filter=+<src/lcd/menu/menu_media.cpp>
232 234
 HAS_MENU_MIXER          = src_filter=+<src/lcd/menu/menu_mixer.cpp>
233 235
 HAS_MENU_MMU2           = src_filter=+<src/lcd/menu/menu_mmu2.cpp>
236
+HAS_MENU_PASSWORD       = src_filter=+<src/lcd/menu/menu_password.cpp>
234 237
 HAS_MENU_POWER_MONITOR  = src_filter=+<src/lcd/menu/menu_power_monitor.cpp>
235 238
 HAS_MENU_CUTTER         = src_filter=+<src/lcd/menu/menu_spindle_laser.cpp>
236 239
 HAS_MENU_TEMPERATURE    = src_filter=+<src/lcd/menu/menu_temperature.cpp>
@@ -276,6 +279,7 @@ TEMP_STAT_LEDS          = src_filter=+<src/feature/leds/tempstat.cpp>
276 279
 MAX7219_DEBUG           = src_filter=+<src/feature/max7219.cpp> +<src/gcode/feature/leds/M7219.cpp>
277 280
 MIXING_EXTRUDER         = src_filter=+<src/feature/mixing.cpp> +<src/gcode/feature/mixing/M163-M165.cpp>
278 281
 PRUSA_MMU2              = src_filter=+<src/feature/mmu2> +<src/gcode/feature/prusa_MMU2>
282
+PASSWORD_FEATURE        = src_filter=+<src/feature/password> +<src/gcode/feature/password>
279 283
 ADVANCED_PAUSE_FEATURE  = src_filter=+<src/feature/pause.cpp> +<src/gcode/feature/pause/M600.cpp> +<src/gcode/feature/pause/M603.cpp>
280 284
 AUTO_POWER_CONTROL      = src_filter=+<src/feature/power.cpp>
281 285
 HAS_POWER_MONITOR       = src_filter=+<src/feature/power_monitor.cpp> +<src/gcode/feature/power_monitor>

Loading…
Cancel
Save