Browse Source

Merge picopass from https://gitlab.com/bettse/picopass

WillyJL 7 months ago
parent
commit
d47ba28007

+ 5 - 3
picopass/picopass.c

@@ -99,11 +99,13 @@ Picopass* picopass_alloc() {
     picopass->plugin_wiegand_manager =
         plugin_manager_alloc(PLUGIN_APP_ID, PLUGIN_API_VERSION, firmware_api_interface);
     picopass->plugin_wiegand = NULL;
-    if(plugin_manager_load_single(picopass->plugin_wiegand_manager, APP_ASSETS_PATH("plugins/plugin_wiegand.fal")) !=
+    if(plugin_manager_load_single(
+           picopass->plugin_wiegand_manager, APP_ASSETS_PATH("plugins/plugin_wiegand.fal")) !=
        PluginManagerErrorNone) {
         FURI_LOG_E(TAG, "Failed to load Wiegand plugin");
-    } else if (plugin_manager_get_count(picopass->plugin_wiegand_manager)) {
-        picopass->plugin_wiegand = (PluginWiegand*)plugin_manager_get_ep(picopass->plugin_wiegand_manager, 0);
+    } else if(plugin_manager_get_count(picopass->plugin_wiegand_manager)) {
+        picopass->plugin_wiegand =
+            (PluginWiegand*)plugin_manager_get_ep(picopass->plugin_wiegand_manager, 0);
         if(strcmp(picopass->plugin_wiegand->name, "Plugin Wiegand") != 0) {
             FURI_LOG_E(TAG, "Tried to load invalid Wiegand plugin");
             picopass->plugin_wiegand = NULL;

+ 0 - 16
picopass/scenes/picopass_scene_read_card_success.c

@@ -71,12 +71,6 @@ void picopass_scene_read_card_success_on_enter(void* context) {
             furi_string_cat_printf(credential_str, "Non-HID CSN");
         }
 
-        widget_add_button_element(
-            widget,
-            GuiButtonTypeCenter,
-            "Menu",
-            picopass_scene_read_card_success_widget_callback,
-            picopass);
         widget_add_button_element(
             widget,
             GuiButtonTypeRight,
@@ -97,13 +91,6 @@ void picopass_scene_read_card_success_on_enter(void* context) {
         furi_string_cat_printf(credential_str, "Config Card");
     } else if(empty) {
         furi_string_cat_printf(credential_str, "Empty");
-
-        widget_add_button_element(
-            widget,
-            GuiButtonTypeCenter,
-            "Menu",
-            picopass_scene_read_card_success_widget_callback,
-            picopass);
     } else if(pacs->bitLength == 0 || pacs->bitLength == 255) {
         // Neither of these are valid.  Indicates the block was all 0x00 or all 0xff
         if(SE) {
@@ -219,9 +206,6 @@ bool picopass_scene_read_card_success_on_event(void* context, SceneManagerEvent
             picopass_device_set_name(picopass->dev, "");
             scene_manager_next_scene(picopass->scene_manager, PicopassSceneCardMenu);
             consumed = true;
-        } else if(event.event == GuiButtonTypeCenter) {
-            consumed = scene_manager_search_and_switch_to_another_scene(
-                picopass->scene_manager, PicopassSceneStart);
         }
     } else if(event.type == SceneManagerEventTypeBack) {
         scene_manager_search_and_switch_to_previous_scene(

+ 224 - 0
picopass/web/dark.css

@@ -0,0 +1,224 @@
+body {
+  font-family: "Courier New", Courier, monospace;
+  margin: 0;
+  background: #000;
+  color: #00ff00;
+  font-size: 18px;
+  letter-spacing: 0.03em;
+  line-height: 1.6;
+  text-shadow: 0 0 2px #00ff00, 0 0 10px #008800;
+  cursor: crosshair;
+}
+
+nav {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  background: #111;
+  border-bottom: 2px solid #00ff00;
+  padding: 0.7rem 2rem;
+  font-size: 1.25rem;
+}
+
+.logo {
+  display: flex;
+  align-items: center;
+}
+.logo img {
+  width: 32px;
+  height: 32px;
+  margin-right: 10px;
+  border: 1px solid #ff00ff;
+  box-shadow: 0 0 8px #ff00ff;
+  image-rendering: pixelated;
+  filter: invert(0.8);
+}
+.logo span {
+  color: #00ff00;
+  font-weight: bold;
+  letter-spacing: 2px;
+  font-size: 1.4rem;
+  text-transform: uppercase;
+}
+
+.download-btn {
+  background: #000;
+  color: #00ff00;
+  border: 2px solid #00ff00;
+  border-radius: 0;
+  padding: 0.3rem 2rem;
+  font-family: inherit;
+  font-size: 1rem;
+  text-decoration: none;
+  font-weight: bold;
+  box-shadow: 0 0 10px #00ff00;
+  transition: background 0.2s, color 0.2s;
+}
+.download-btn:hover, .cta-btn:hover {
+  background: #00ff00;
+  color: #000;
+  text-shadow: none;
+}
+
+header {
+  border: 2px solid #00ff00;
+  margin: 32px auto 24px auto;
+  max-width: 850px;
+  background: #111;
+  box-shadow: 0 0 24px #00ff00;
+  padding: 2rem 1rem 2rem 1rem;
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+}
+.header-content {
+  max-width: 520px;
+}
+header h1 {
+  font-size: 2.2rem;
+  margin: 0 0 1.3rem 0;
+  color: #00ff00;
+  font-family: "Courier New", Courier, monospace;
+  text-transform: uppercase;
+  letter-spacing: 2px;
+  border-bottom: 1px dashed #00ff00;
+  padding-bottom: 0.4rem;
+}
+header p {
+  color: #0f0;
+  margin-bottom: 1.5rem;
+  font-size: 1.15rem;
+}
+
+.cta-btn {
+  background: #000;
+  color: #00ff00;
+  border: 2px solid #00ff00;
+  border-radius: 0;
+  padding: 0.5rem 2.2rem;
+  font-size: 1.1rem;
+  font-family: inherit;
+  font-weight: bold;
+  text-decoration: none;
+  box-shadow: 0 0 10px #00ff00;
+}
+
+.device-img {
+  width: 240px;
+  max-width: 90vw;
+  margin-left: 2.2rem;
+  margin-top: 1rem;
+  border: 1px solid #00ff00;
+  background: #000;
+  box-shadow: 0 0 20px #00ff00;
+  image-rendering: pixelated;
+}
+
+section {
+  border: 2px dashed #00ff00;
+  padding: 1.5rem 1.4rem 0.6rem 1.4rem;
+  margin: 1rem auto 1.5rem auto;
+  max-width: 800px;
+  background: #111;
+  box-shadow: 0 0 12px #00ff00;
+  position: relative;
+}
+
+section h2 {
+  color: #00ff00;
+  font-size: 1.5rem;
+  font-family: "Courier New", Courier, monospace;
+  text-transform: uppercase;
+  border-bottom: 1px solid #00ff00;
+  padding-bottom: 0.2rem;
+  margin-top: 0;
+  margin-bottom: 1rem;
+  letter-spacing: 2px;
+}
+
+ul, ol {
+  margin-left: 1.2rem;
+  font-size: 1.09rem;
+  background: #000;
+  border: 1px dashed #00ff00;
+  padding: 0.6rem 1.2rem;
+  color: #00ff00;
+}
+
+li {
+  margin-bottom: 0.7rem;
+}
+
+a {
+  color: #00ff00;
+  text-decoration: underline;
+  font-weight: bold;
+}
+a:hover {
+  color: #000;
+  background: #00ff00;
+  text-shadow: none;
+}
+
+.download-link, .source-link {
+  color: #00ff00;
+  border-bottom: 1px dashed #00ff00;
+  background: #000;
+  display: inline-block;
+  margin: 0.5rem 0;
+  font-family: inherit;
+  font-size: 1rem;
+  padding: 0.1rem 0.5rem;
+  transition: background 0.2s, color 0.2s;
+}
+.download-link:hover, .source-link:hover {
+  color: #000;
+  background: #00ff00;
+  border-bottom: 1px solid #00ff00;
+}
+
+footer {
+  text-align: center;
+  padding: 1.4rem 1rem;
+  color: #00ff00;
+  background: #000;
+  font-size: 1.1rem;
+  border-top: 2px solid #00ff00;
+  letter-spacing: 2px;
+  font-family: "Courier New", Courier, monospace;
+}
+
+::-webkit-scrollbar {
+  width: 10px;
+  background: #111;
+}
+::-webkit-scrollbar-thumb {
+  background: #00ff00;
+  border-radius: 0;
+}
+
+@media (max-width: 900px) {
+  header, section {
+    max-width: 99vw;
+    margin-left: 0.5vw;
+    margin-right: 0.5vw;
+  }
+  .device-img {
+    margin-left: 0;
+    margin-top: 2.2rem;
+    width: 90vw;
+  }
+}
+@media (max-width: 700px) {
+  header {
+    flex-direction: column;
+    text-align: center;
+    padding: 1rem 0.3rem;
+  }
+  .device-img {
+    margin: 2rem 0 0 0;
+    width: 80vw;
+  }
+}

BIN
picopass/web/flipper.png


BIN
picopass/web/icon.png


+ 60 - 0
picopass/web/index.html

@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>PicoPass for Flipper Zero</title>
+  <meta name="description" content="PicoPass - A Flipper Zero app for reading and emulating HID iCLASS cards.">
+  <link rel="icon" href="icon.png">
+  <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@700;400&display=swap" rel="stylesheet">
+  <link rel="stylesheet" href="light.css" media="(prefers-color-scheme: light)">
+  <link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">
+</head>
+<body>
+  <nav>
+    <div class="logo">
+      <img src="icon.png" alt="PicoPass Icon">
+      <span>PicoPass</span>
+    </div>
+    <a href="https://lab.flipper.net/apps/picopass" class="download-btn">Download</a>
+  </nav>
+  <header>
+    <div class="header-content">
+      <h1>PicoPass for Flipper Zero</h1>
+      <p>Read, decode, and emulate HID iCLASS cards right from your Flipper Zero!</p>
+      <a href="https://lab.flipper.net/apps/picopass" class="cta-btn">Get PicoPass</a>
+    </div>
+    <img class="device-img" src="./flipper.png" alt="Flipper Zero Device">
+  </header>
+  <section id="features">
+    <h2>Features</h2>
+    <ul>
+      <li>🪪 <b>Card Reading:</b> Scan and decode HID iCLASS cards.</li>
+      <li>🔓 <b>Emulation:</b> Emulate iCLASS cards for testing and demonstration.</li>
+      <li>⚡ <b>Easy to Use:</b> Clean interface designed for the Flipper Zero.</li>
+      <li>🔒 <b>Open Source:</b> Auditable and hackable for your peace of mind.</li>
+    </ul>
+  </section>
+  <section id="how">
+    <h2>How It Works</h2>
+    <ol>
+      <li>Install the PicoPass app on your Flipper Zero.</li>
+      <li>Navigate to PicoPass in the menu.</li>
+      <li>Hold your iCLASS card to the device and follow on-screen instructions.</li>
+      <li>Save card data or emulate instantly.</li>
+    </ol>
+  </section>
+  <section id="download">
+    <h2>Download</h2>
+    <p>
+      <a href="https://lab.flipper.net/apps/picopass" target="_blank" class="download-link">Get PicoPass from the Flipper App Catalog</a>
+    </p>
+    <p>
+      <a href="https://gitlab.com/bettse/picopass" target="_blank" class="source-link">View Source on GitLab</a>
+    </p>
+  </section>
+  <footer>
+    <p>Made with 🧡 for the Flipper Zero community. © 2025 bettse</p>
+  </footer>
+</body>
+</html>

+ 135 - 0
picopass/web/light.css

@@ -0,0 +1,135 @@
+body {
+  font-family: 'Montserrat', sans-serif;
+  margin: 0;
+  background: #1a1c1f;
+  color: #f6f6f6;
+}
+nav {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  background: #131416;
+  padding: 1rem 2rem;
+  position: sticky;
+  top: 0;
+  z-index: 100;
+}
+.logo {
+  display: flex;
+  align-items: center;
+}
+.logo img {
+  width: 36px;
+  height: 36px;
+  margin-right: 10px;
+  border-radius: 8px;
+  box-shadow: 0 1px 4px rgba(0,0,0,0.12);
+  image-rendering: pixelated;
+  filter: invert(0.8);
+}
+.logo span {
+  font-size: 1.5rem;
+  font-weight: 700;
+  letter-spacing: 1px;
+  color: #ff9300;
+}
+.download-btn {
+  background: #ff9300;
+  color: #1a1c1f;
+  padding: 0.6rem 1.2rem;
+  border-radius: 30px;
+  text-decoration: none;
+  font-weight: bold;
+  transition: background 0.2s;
+}
+.download-btn:hover, .cta-btn:hover {
+  background: #ffb347;
+  color: #1a1c1f;
+}
+header {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  justify-content: center;
+  padding: 4rem 2rem 2rem 2rem;
+  background: linear-gradient(90deg, #ff9300 0%, #ffb347 100%);
+  color: #1a1c1f;
+}
+.header-content {
+  max-width: 500px;
+}
+header h1 {
+  font-size: 2.5rem;
+  margin: 0 0 1rem 0;
+}
+header p {
+  font-size: 1.25rem;
+  margin-bottom: 2rem;
+}
+.cta-btn {
+  background: #1a1c1f;
+  color: #ff9300;
+  padding: 0.8rem 2rem;
+  border-radius: 30px;
+  text-decoration: none;
+  font-size: 1.1rem;
+  font-weight: bold;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+  transition: background 0.2s, color 0.2s;
+}
+.device-img {
+  width: 260px;
+  max-width: 90vw;
+  margin-left: 2rem;
+  border-radius: 30px;
+  box-shadow: 0 6px 24px rgba(0,0,0,0.18);
+}
+section {
+  padding: 2.5rem 1rem 0 1rem;
+  max-width: 820px;
+  margin: auto;
+}
+section h2 {
+  color: #ff9300;
+  font-size: 2rem;
+  margin-bottom: 1rem;
+}
+ul, ol {
+  font-size: 1.15rem;
+  line-height: 1.75;
+  margin-left: 1.5rem;
+  margin-bottom: 1rem;
+}
+.download-link, .source-link {
+  display: inline-block;
+  margin: 0.5rem 0;
+  font-weight: bold;
+  color: #ff9300;
+  text-decoration: none;
+  border-bottom: 2px solid #ff9300;
+  transition: color 0.2s;
+}
+.download-link:hover, .source-link:hover {
+  color: #ffb347;
+  border-color: #ffb347;
+}
+footer {
+  text-align: center;
+  padding: 2rem 1rem;
+  color: #ff9300;
+  background: #131416;
+  margin-top: 2rem;
+  font-size: 1rem;
+}
+
+@media (max-width: 700px) {
+  header {
+    flex-direction: column;
+    text-align: center;
+    padding: 2rem 1rem;
+  }
+  .device-img {
+    margin: 2rem 0 0 0;
+    width: 80vw;
+  }
+}