[FL-1419] new iButton cli (#521)
* iButton, helpers: add destructor * iButton app: new approach to cli commands, cli read * iButton app: cli write * iButton app: cli emulate * iButton app: remove old cli commands * iButton app: use unique_ptr for worker * iButton app: remove obsolete cli help * iButton app: fix help and key type parsing
This commit is contained in:
		
							parent
							
								
									9943c93189
								
							
						
					
					
						commit
						89dd1ff925
					
				| @ -47,6 +47,7 @@ void nfc_cli_init(); | |||||||
| void subghz_cli_init(); | void subghz_cli_init(); | ||||||
| void bt_cli_init(); | void bt_cli_init(); | ||||||
| void lfrfid_cli_init(); | void lfrfid_cli_init(); | ||||||
|  | void ibutton_cli_init(); | ||||||
| 
 | 
 | ||||||
| const FlipperApplication FLIPPER_SERVICES[] = { | const FlipperApplication FLIPPER_SERVICES[] = { | ||||||
| #ifdef SRV_CLI | #ifdef SRV_CLI | ||||||
| @ -216,6 +217,9 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | |||||||
| #ifdef APP_LF_RFID | #ifdef APP_LF_RFID | ||||||
|     lfrfid_cli_init, |     lfrfid_cli_init, | ||||||
| #endif | #endif | ||||||
|  | #ifdef APP_IBUTTON | ||||||
|  |     ibutton_cli_init, | ||||||
|  | #endif | ||||||
| #ifdef SRV_BT | #ifdef SRV_BT | ||||||
|     bt_cli_init, |     bt_cli_init, | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| #include <callback-connector.h> | #include <callback-connector.h> | ||||||
| 
 | 
 | ||||||
| KeyEmulator::~KeyEmulator() { | KeyEmulator::~KeyEmulator() { | ||||||
|     onewire_slave->stop(); |     stop(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| KeyEmulator::KeyEmulator(OneWireSlave* _onewire_slave) | KeyEmulator::KeyEmulator(OneWireSlave* _onewire_slave) | ||||||
|  | |||||||
| @ -49,3 +49,6 @@ KeyWorker::KeyWorker(const GpioPin* one_wire_gpio) | |||||||
|     , key_emulator{&onewire_slave} |     , key_emulator{&onewire_slave} | ||||||
|     , key_writer{&onewire_master} { |     , key_writer{&onewire_master} { | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | KeyWorker::~KeyWorker() { | ||||||
|  | } | ||||||
| @ -23,6 +23,7 @@ public: | |||||||
|     void stop_write(); |     void stop_write(); | ||||||
| 
 | 
 | ||||||
|     KeyWorker(const GpioPin* one_wire_gpio); |     KeyWorker(const GpioPin* one_wire_gpio); | ||||||
|  |     ~KeyWorker(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     // one wire
 |     // one wire
 | ||||||
|  | |||||||
| @ -5,6 +5,10 @@ KeyWriter::KeyWriter(OneWireMaster* _onewire_master) { | |||||||
|     onewire_master = _onewire_master; |     onewire_master = _onewire_master; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | KeyWriter::~KeyWriter() { | ||||||
|  |     stop(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| KeyWriter::Error KeyWriter::write(iButtonKey* key) { | KeyWriter::Error KeyWriter::write(iButtonKey* key) { | ||||||
|     return write_internal(key); |     return write_internal(key); | ||||||
| } | } | ||||||
|  | |||||||
| @ -28,171 +28,14 @@ void iButtonApp::run(void) { | |||||||
|     scenes[current_scene]->on_exit(this); |     scenes[current_scene]->on_exit(this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonApp::print_key_data(void) { |  | ||||||
|     uint8_t* key_data = key.get_data(); |  | ||||||
|     switch(key.get_key_type()) { |  | ||||||
|     case iButtonKeyType::KeyDallas: |  | ||||||
|         printf( |  | ||||||
|             "Dallas %02X %02X %02X %02X %02X %02X %02X %02X\r\n", |  | ||||||
|             key_data[0], |  | ||||||
|             key_data[1], |  | ||||||
|             key_data[2], |  | ||||||
|             key_data[3], |  | ||||||
|             key_data[4], |  | ||||||
|             key_data[5], |  | ||||||
|             key_data[6], |  | ||||||
|             key_data[7]); |  | ||||||
|         break; |  | ||||||
|     case iButtonKeyType::KeyCyfral: |  | ||||||
|         printf("Cyfral %02X %02X\r\n", key_data[0], key_data[1]); |  | ||||||
|         break; |  | ||||||
|     case iButtonKeyType::KeyMetakom: |  | ||||||
|         printf( |  | ||||||
|             "Metakom %02X %02X %02X %02X\r\n", key_data[0], key_data[1], key_data[2], key_data[3]); |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool iButtonApp::read_hex_byte(string_t args, uint8_t* byte) { |  | ||||||
|     char* endptr; |  | ||||||
|     *byte = strtoul(string_get_cstr(args), &endptr, 16); |  | ||||||
|     if(*endptr == '\0') { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|     size_t ws = string_search_char(args, ' '); |  | ||||||
|     if(ws != 2) { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|     string_right(args, ws); |  | ||||||
|     string_strim(args); |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void iButtonApp::cli_cmd_callback(Cli* cli, string_t args, void* context) { |  | ||||||
|     iButtonApp::Scene scene; |  | ||||||
|     string_t cmd; |  | ||||||
|     string_init(cmd); |  | ||||||
|     if(!string_cmp_str(args, "read")) { |  | ||||||
|         scene = iButtonApp::Scene::SceneCliRead; |  | ||||||
|         printf("Reading key ...\r\n"); |  | ||||||
|     } else { |  | ||||||
|         // Parse write / emulate commands
 |  | ||||||
|         size_t ws = string_search_char(args, ' '); |  | ||||||
|         if(ws == STRING_FAILURE) { |  | ||||||
|             printf("Incorrect input. Try tm <read | write | emulate> [key_type] [key_data]"); |  | ||||||
|             string_clear(cmd); |  | ||||||
|             return; |  | ||||||
|         } else { |  | ||||||
|             string_set_n(cmd, args, 0, ws); |  | ||||||
|             string_right(args, ws); |  | ||||||
|             string_strim(args); |  | ||||||
|         } |  | ||||||
|         if(!string_cmp_str(cmd, "write")) { |  | ||||||
|             scene = iButtonApp::Scene::SceneCliWrite; |  | ||||||
|         } else if(!string_cmp_str(cmd, "emulate")) { |  | ||||||
|             scene = iButtonApp::Scene::SceneCliEmulate; |  | ||||||
|         } else { |  | ||||||
|             printf("Incorrect input. Try tm <write | emulate> <key_type> <key_data>"); |  | ||||||
|             string_clear(cmd); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         string_clear(cmd); |  | ||||||
|         // Parse key type
 |  | ||||||
|         string_t key_type; |  | ||||||
|         string_init(key_type); |  | ||||||
|         ws = string_search_char(args, ' '); |  | ||||||
|         string_set_n(key_type, args, 0, ws); |  | ||||||
|         uint8_t bytes_to_read = 0; |  | ||||||
|         if(!string_cmp_str(key_type, "0")) { |  | ||||||
|             key.set_type(iButtonKeyType::KeyDallas); |  | ||||||
|             bytes_to_read = 8; |  | ||||||
|         } else if(!string_cmp_str(key_type, "1")) { |  | ||||||
|             key.set_type(iButtonKeyType::KeyCyfral); |  | ||||||
|             bytes_to_read = 2; |  | ||||||
|         } else if(!string_cmp_str(key_type, "2")) { |  | ||||||
|             key.set_type(iButtonKeyType::KeyMetakom); |  | ||||||
|             bytes_to_read = 4; |  | ||||||
|         } else { |  | ||||||
|             printf("Incorrect key type. Try 0 - KeyDallas, 1 - KeyCyfral, 2 - KeyMetakom"); |  | ||||||
|             string_clear(key_type); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         string_clear(key_type); |  | ||||||
|         // Read key data
 |  | ||||||
|         string_right(args, 1); |  | ||||||
|         string_strim(args); |  | ||||||
|         uint8_t key_data[8] = {}; |  | ||||||
|         uint8_t i = 0; |  | ||||||
|         bool ret = true; |  | ||||||
|         while((i < bytes_to_read) && ret) { |  | ||||||
|             ret = read_hex_byte(args, &key_data[i++]); |  | ||||||
|         } |  | ||||||
|         if(i != bytes_to_read) { |  | ||||||
|             printf("Incorrect key data. Type %d key data hex digits", bytes_to_read); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         key.set_data(key_data, bytes_to_read); |  | ||||||
|         if(scene == iButtonApp::Scene::SceneCliWrite) { |  | ||||||
|             printf("Writing key "); |  | ||||||
|         } else { |  | ||||||
|             printf("Emulating key "); |  | ||||||
|         } |  | ||||||
|         print_key_data(); |  | ||||||
|     } |  | ||||||
|     switch_to_next_scene(scene); |  | ||||||
|     // Wait return event
 |  | ||||||
|     iButtonApp::CliEvent result; |  | ||||||
|     if(osMessageQueueGet(cli_event_result, &result, NULL, osWaitForever) != osOK) { |  | ||||||
|         printf("Command execution error"); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     // Process return event
 |  | ||||||
|     switch(result) { |  | ||||||
|     case iButtonApp::CliEvent::CliReadSuccess: |  | ||||||
|     case iButtonApp::CliEvent::CliReadCRCError: |  | ||||||
|         print_key_data(); |  | ||||||
|         if(result == iButtonApp::CliEvent::CliReadCRCError) { |  | ||||||
|             printf("Warning: invalid CRC"); |  | ||||||
|         } |  | ||||||
|         break; |  | ||||||
|     case iButtonApp::CliEvent::CliReadNotKeyError: |  | ||||||
|         printf("Read error: not a key"); |  | ||||||
|         break; |  | ||||||
|     case iButtonApp::CliEvent::CliTimeout: |  | ||||||
|         printf("Timeout error"); |  | ||||||
|         break; |  | ||||||
|     case iButtonApp::CliEvent::CliInterrupt: |  | ||||||
|         printf("Command interrupted"); |  | ||||||
|         break; |  | ||||||
|     case iButtonApp::CliEvent::CliWriteSuccess: |  | ||||||
|         printf("Write success"); |  | ||||||
|         break; |  | ||||||
|     case iButtonApp::CliEvent::CliWriteFail: |  | ||||||
|         printf("Write fail"); |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
|     return; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void iButtonApp::cli_send_event(iButtonApp::CliEvent scene) { |  | ||||||
|     osMessageQueuePut(cli_event_result, &scene, 0, osWaitForever); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| iButtonApp::iButtonApp() { | iButtonApp::iButtonApp() { | ||||||
|     api_hal_power_insomnia_enter(); |     api_hal_power_insomnia_enter(); | ||||||
| 
 | 
 | ||||||
|     cli_event_result = osMessageQueueNew(1, sizeof(iButtonApp::Scene), NULL); |  | ||||||
|     key_worker = new KeyWorker(&ibutton_gpio); |     key_worker = new KeyWorker(&ibutton_gpio); | ||||||
|     sd_ex_api = static_cast<SdCard_Api*>(furi_record_open("sdcard-ex")); |     sd_ex_api = static_cast<SdCard_Api*>(furi_record_open("sdcard-ex")); | ||||||
|     fs_api = static_cast<FS_Api*>(furi_record_open("sdcard")); |     fs_api = static_cast<FS_Api*>(furi_record_open("sdcard")); | ||||||
|     cli = static_cast<Cli*>(furi_record_open("cli")); |  | ||||||
|     notification = static_cast<NotificationApp*>(furi_record_open("notification")); |     notification = static_cast<NotificationApp*>(furi_record_open("notification")); | ||||||
| 
 | 
 | ||||||
|     auto callback = cbc::obtain_connector(this, &iButtonApp::cli_cmd_callback); |  | ||||||
|     cli_add_command(cli, "tm", callback, cli); |  | ||||||
| 
 |  | ||||||
|     // we need random
 |     // we need random
 | ||||||
|     srand(DWT->CYCCNT); |     srand(DWT->CYCCNT); | ||||||
| } | } | ||||||
| @ -202,11 +45,8 @@ iButtonApp::~iButtonApp() { | |||||||
| 
 | 
 | ||||||
|     furi_record_close("sdcard-ex"); |     furi_record_close("sdcard-ex"); | ||||||
|     furi_record_close("sdcard"); |     furi_record_close("sdcard"); | ||||||
|     furi_record_close("cli"); |  | ||||||
|     furi_record_close("notification"); |     furi_record_close("notification"); | ||||||
| 
 | 
 | ||||||
|     osMessageQueueDelete(cli_event_result); |  | ||||||
| 
 |  | ||||||
|     for(std::map<Scene, iButtonScene*>::iterator it = scenes.begin(); it != scenes.end(); ++it) { |     for(std::map<Scene, iButtonScene*>::iterator it = scenes.begin(); it != scenes.end(); ++it) { | ||||||
|         delete it->second; |         delete it->second; | ||||||
|         scenes.erase(it); |         scenes.erase(it); | ||||||
|  | |||||||
| @ -6,19 +6,16 @@ | |||||||
| #include "scene/ibutton-scene-generic.h" | #include "scene/ibutton-scene-generic.h" | ||||||
| #include "scene/ibutton-scene-start.h" | #include "scene/ibutton-scene-start.h" | ||||||
| #include "scene/ibutton-scene-read.h" | #include "scene/ibutton-scene-read.h" | ||||||
| #include "scene/ibutton-scene-cli-read.h" |  | ||||||
| #include "scene/ibutton-scene-read-crc-error.h" | #include "scene/ibutton-scene-read-crc-error.h" | ||||||
| #include "scene/ibutton-scene-read-not-key-error.h" | #include "scene/ibutton-scene-read-not-key-error.h" | ||||||
| #include "scene/ibutton-scene-read-success.h" | #include "scene/ibutton-scene-read-success.h" | ||||||
| #include "scene/ibutton-scene-readed-key-menu.h" | #include "scene/ibutton-scene-readed-key-menu.h" | ||||||
| #include "scene/ibutton-scene-write.h" | #include "scene/ibutton-scene-write.h" | ||||||
| #include "scene/ibutton-scene-cli-write.h" |  | ||||||
| #include "scene/ibutton-scene-write-success.h" | #include "scene/ibutton-scene-write-success.h" | ||||||
| #include "scene/ibutton-scene-saved-key-menu.h" | #include "scene/ibutton-scene-saved-key-menu.h" | ||||||
| #include "scene/ibutton-scene-delete-confirm.h" | #include "scene/ibutton-scene-delete-confirm.h" | ||||||
| #include "scene/ibutton-scene-delete-success.h" | #include "scene/ibutton-scene-delete-success.h" | ||||||
| #include "scene/ibutton-scene-emulate.h" | #include "scene/ibutton-scene-emulate.h" | ||||||
| #include "scene/ibutton-scene-cli-emulate.h" |  | ||||||
| #include "scene/ibutton-scene-save-name.h" | #include "scene/ibutton-scene-save-name.h" | ||||||
| #include "scene/ibutton-scene-save-success.h" | #include "scene/ibutton-scene-save-success.h" | ||||||
| #include "scene/ibutton-scene-info.h" | #include "scene/ibutton-scene-info.h" | ||||||
| @ -49,16 +46,13 @@ public: | |||||||
|         SceneExit, |         SceneExit, | ||||||
|         SceneStart, |         SceneStart, | ||||||
|         SceneRead, |         SceneRead, | ||||||
|         SceneCliRead, |  | ||||||
|         SceneReadNotKeyError, |         SceneReadNotKeyError, | ||||||
|         SceneReadCRCError, |         SceneReadCRCError, | ||||||
|         SceneReadSuccess, |         SceneReadSuccess, | ||||||
|         SceneReadedKeyMenu, |         SceneReadedKeyMenu, | ||||||
|         SceneWrite, |         SceneWrite, | ||||||
|         SceneCliWrite, |  | ||||||
|         SceneWriteSuccess, |         SceneWriteSuccess, | ||||||
|         SceneEmulate, |         SceneEmulate, | ||||||
|         SceneCliEmulate, |  | ||||||
|         SceneSavedKeyMenu, |         SceneSavedKeyMenu, | ||||||
|         SceneDeleteConfirm, |         SceneDeleteConfirm, | ||||||
|         SceneDeleteSuccess, |         SceneDeleteSuccess, | ||||||
| @ -70,16 +64,6 @@ public: | |||||||
|         SceneAddValue, |         SceneAddValue, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     enum class CliEvent : uint8_t { |  | ||||||
|         CliReadSuccess, |  | ||||||
|         CliReadCRCError, |  | ||||||
|         CliReadNotKeyError, |  | ||||||
|         CliWriteSuccess, |  | ||||||
|         CliWriteFail, |  | ||||||
|         CliTimeout, |  | ||||||
|         CliInterrupt, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     iButtonAppViewManager* get_view_manager(); |     iButtonAppViewManager* get_view_manager(); | ||||||
|     void switch_to_next_scene(Scene index); |     void switch_to_next_scene(Scene index); | ||||||
|     void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list); |     void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list); | ||||||
| @ -110,9 +94,6 @@ public: | |||||||
|     char* get_file_name(); |     char* get_file_name(); | ||||||
|     uint8_t get_file_name_size(); |     uint8_t get_file_name_size(); | ||||||
| 
 | 
 | ||||||
|     void cli_cmd_callback(Cli* cli, string_t args, void* context); |  | ||||||
|     void cli_send_event(CliEvent scene); |  | ||||||
| 
 |  | ||||||
|     void generate_random_name(char* name, uint8_t max_name_size); |     void generate_random_name(char* name, uint8_t max_name_size); | ||||||
| 
 | 
 | ||||||
|     bool save_key(const char* key_name); |     bool save_key(const char* key_name); | ||||||
| @ -123,21 +104,17 @@ private: | |||||||
|     std::list<Scene> previous_scenes_list = {Scene::SceneExit}; |     std::list<Scene> previous_scenes_list = {Scene::SceneExit}; | ||||||
|     Scene current_scene = Scene::SceneStart; |     Scene current_scene = Scene::SceneStart; | ||||||
|     iButtonAppViewManager view; |     iButtonAppViewManager view; | ||||||
|     osMessageQueueId_t cli_event_result; |  | ||||||
| 
 | 
 | ||||||
|     std::map<Scene, iButtonScene*> scenes = { |     std::map<Scene, iButtonScene*> scenes = { | ||||||
|         {Scene::SceneStart, new iButtonSceneStart()}, |         {Scene::SceneStart, new iButtonSceneStart()}, | ||||||
|         {Scene::SceneRead, new iButtonSceneRead()}, |         {Scene::SceneRead, new iButtonSceneRead()}, | ||||||
|         {Scene::SceneCliRead, new iButtonSceneCliRead()}, |  | ||||||
|         {Scene::SceneReadCRCError, new iButtonSceneReadCRCError()}, |         {Scene::SceneReadCRCError, new iButtonSceneReadCRCError()}, | ||||||
|         {Scene::SceneReadNotKeyError, new iButtonSceneReadNotKeyError()}, |         {Scene::SceneReadNotKeyError, new iButtonSceneReadNotKeyError()}, | ||||||
|         {Scene::SceneReadSuccess, new iButtonSceneReadSuccess()}, |         {Scene::SceneReadSuccess, new iButtonSceneReadSuccess()}, | ||||||
|         {Scene::SceneReadedKeyMenu, new iButtonSceneReadedKeyMenu()}, |         {Scene::SceneReadedKeyMenu, new iButtonSceneReadedKeyMenu()}, | ||||||
|         {Scene::SceneWrite, new iButtonSceneWrite()}, |         {Scene::SceneWrite, new iButtonSceneWrite()}, | ||||||
|         {Scene::SceneCliWrite, new iButtonSceneCliWrite()}, |  | ||||||
|         {Scene::SceneWriteSuccess, new iButtonSceneWriteSuccess()}, |         {Scene::SceneWriteSuccess, new iButtonSceneWriteSuccess()}, | ||||||
|         {Scene::SceneEmulate, new iButtonSceneEmulate()}, |         {Scene::SceneEmulate, new iButtonSceneEmulate()}, | ||||||
|         {Scene::SceneCliEmulate, new iButtonSceneCliEmulate()}, |  | ||||||
|         {Scene::SceneSavedKeyMenu, new iButtonSceneSavedKeyMenu()}, |         {Scene::SceneSavedKeyMenu, new iButtonSceneSavedKeyMenu()}, | ||||||
|         {Scene::SceneDeleteConfirm, new iButtonSceneDeleteConfirm()}, |         {Scene::SceneDeleteConfirm, new iButtonSceneDeleteConfirm()}, | ||||||
|         {Scene::SceneDeleteSuccess, new iButtonSceneDeleteSuccess()}, |         {Scene::SceneDeleteSuccess, new iButtonSceneDeleteSuccess()}, | ||||||
| @ -164,9 +141,6 @@ private: | |||||||
| 
 | 
 | ||||||
|     NotificationApp* notification; |     NotificationApp* notification; | ||||||
| 
 | 
 | ||||||
|     bool read_hex_byte(string_t arg, uint8_t* byte); |  | ||||||
|     void print_key_data(void); |  | ||||||
| 
 |  | ||||||
|     static const char* app_folder; |     static const char* app_folder; | ||||||
|     static const char* app_extension; |     static const char* app_extension; | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										234
									
								
								applications/ibutton/ibutton-cli.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								applications/ibutton/ibutton-cli.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,234 @@ | |||||||
|  | #include <furi.h> | ||||||
|  | #include <api-hal.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <cli/cli.h> | ||||||
|  | #include <args.h> | ||||||
|  | 
 | ||||||
|  | #include "helpers/key-info.h" | ||||||
|  | #include "helpers/key-worker.h" | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | void ibutton_cli(Cli* cli, string_t args, void* context); | ||||||
|  | 
 | ||||||
|  | // app cli function
 | ||||||
|  | extern "C" void ibutton_cli_init() { | ||||||
|  |     Cli* cli = static_cast<Cli*>(furi_record_open("cli")); | ||||||
|  |     cli_add_command(cli, "tm", ibutton_cli, cli); | ||||||
|  |     furi_record_close("cli"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ibutton_cli_print_usage() { | ||||||
|  |     printf("Usage:\r\n"); | ||||||
|  |     printf("tm read\r\n"); | ||||||
|  |     printf("tm <write | emulate> <key_type> <key_data>\r\n"); | ||||||
|  |     printf("\t<key_type> choose from:\r\n"); | ||||||
|  |     printf("\tDallas (8 bytes key_data)\r\n"); | ||||||
|  |     printf("\tCyfral (2 bytes key_data)\r\n"); | ||||||
|  |     printf("\tMetakom (4 bytes key_data)\r\n"); | ||||||
|  |     printf("\t<key_data> are hex-formatted\r\n"); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | bool ibutton_cli_get_key_type(string_t data, iButtonKeyType* type) { | ||||||
|  |     bool result = false; | ||||||
|  | 
 | ||||||
|  |     if(string_cmp_str(data, "Dallas") == 0 || string_cmp_str(data, "dallas") == 0) { | ||||||
|  |         result = true; | ||||||
|  |         *type = iButtonKeyType::KeyDallas; | ||||||
|  |     } else if(string_cmp_str(data, "Cyfral") == 0 || string_cmp_str(data, "cyfral") == 0) { | ||||||
|  |         result = true; | ||||||
|  |         *type = iButtonKeyType::KeyCyfral; | ||||||
|  |     } else if(string_cmp_str(data, "Metakom") == 0 || string_cmp_str(data, "metakom") == 0) { | ||||||
|  |         result = true; | ||||||
|  |         *type = iButtonKeyType::KeyMetakom; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ibutton_cli_print_key_data(iButtonKey* key) { | ||||||
|  |     uint8_t* key_data = key->get_data(); | ||||||
|  |     switch(key->get_key_type()) { | ||||||
|  |     case iButtonKeyType::KeyDallas: | ||||||
|  |         printf( | ||||||
|  |             "Dallas %02X%02X%02X%02X%02X%02X%02X%02X\r\n", | ||||||
|  |             key_data[0], | ||||||
|  |             key_data[1], | ||||||
|  |             key_data[2], | ||||||
|  |             key_data[3], | ||||||
|  |             key_data[4], | ||||||
|  |             key_data[5], | ||||||
|  |             key_data[6], | ||||||
|  |             key_data[7]); | ||||||
|  |         break; | ||||||
|  |     case iButtonKeyType::KeyCyfral: | ||||||
|  |         printf("Cyfral %02X%02X\r\n", key_data[0], key_data[1]); | ||||||
|  |         break; | ||||||
|  |     case iButtonKeyType::KeyMetakom: | ||||||
|  |         printf("Metakom %02X%02X%02X%02X\r\n", key_data[0], key_data[1], key_data[2], key_data[3]); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ibutton_cli_read(Cli* cli) { | ||||||
|  |     iButtonKey key; | ||||||
|  |     std::unique_ptr<KeyWorker> worker(new KeyWorker(&ibutton_gpio)); | ||||||
|  | 
 | ||||||
|  |     bool exit = false; | ||||||
|  | 
 | ||||||
|  |     worker->start_read(); | ||||||
|  |     printf("Reading iButton...\r\nPress Ctrl+C to abort\r\n"); | ||||||
|  | 
 | ||||||
|  |     while(!exit) { | ||||||
|  |         exit = cli_cmd_interrupt_received(cli); | ||||||
|  | 
 | ||||||
|  |         switch(worker->read(&key)) { | ||||||
|  |         case KeyReader::Error::EMPTY: | ||||||
|  |             break; | ||||||
|  |         case KeyReader::Error::CRC_ERROR: | ||||||
|  |             ibutton_cli_print_key_data(&key); | ||||||
|  |             printf("Warning: invalid CRC\r\n"); | ||||||
|  |             exit = true; | ||||||
|  |             break; | ||||||
|  |         case KeyReader::Error::OK: | ||||||
|  |             ibutton_cli_print_key_data(&key); | ||||||
|  |             exit = true; | ||||||
|  |             break; | ||||||
|  |         case KeyReader::Error::NOT_ARE_KEY: | ||||||
|  |             ibutton_cli_print_key_data(&key); | ||||||
|  |             printf("Warning: not a key\r\n"); | ||||||
|  |             exit = true; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         delay(100); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     worker->stop_read(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void ibutton_cli_write(Cli* cli, string_t args) { | ||||||
|  |     iButtonKey key; | ||||||
|  |     iButtonKeyType type; | ||||||
|  |     std::unique_ptr<KeyWorker> worker(new KeyWorker(&ibutton_gpio)); | ||||||
|  | 
 | ||||||
|  |     bool exit = false; | ||||||
|  |     string_t data; | ||||||
|  |     string_init(data); | ||||||
|  | 
 | ||||||
|  |     if(!args_read_string_and_trim(args, data)) { | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(!ibutton_cli_get_key_type(data, &type)) { | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     key.set_type(type); | ||||||
|  | 
 | ||||||
|  |     if(!args_read_hex_bytes(args, key.get_data(), key.get_type_data_size())) { | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("Writing key "); | ||||||
|  |     ibutton_cli_print_key_data(&key); | ||||||
|  |     printf("Press Ctrl+C to abort\r\n"); | ||||||
|  | 
 | ||||||
|  |     worker->start_write(); | ||||||
|  | 
 | ||||||
|  |     while(!exit) { | ||||||
|  |         exit = cli_cmd_interrupt_received(cli); | ||||||
|  | 
 | ||||||
|  |         KeyWriter::Error result = worker->write(&key); | ||||||
|  | 
 | ||||||
|  |         switch(result) { | ||||||
|  |         case KeyWriter::Error::SAME_KEY: | ||||||
|  |         case KeyWriter::Error::OK: | ||||||
|  |             printf("Write success\r\n"); | ||||||
|  |             exit = true; | ||||||
|  |             break; | ||||||
|  |         case KeyWriter::Error::NO_DETECT: | ||||||
|  |             break; | ||||||
|  |         case KeyWriter::Error::CANNOT_WRITE: | ||||||
|  |             printf("Write fail\r\n"); | ||||||
|  |             exit = true; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     worker->stop_write(); | ||||||
|  | 
 | ||||||
|  |     string_clear(data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void ibutton_cli_emulate(Cli* cli, string_t args) { | ||||||
|  |     iButtonKey key; | ||||||
|  |     iButtonKeyType type; | ||||||
|  |     std::unique_ptr<KeyWorker> worker(new KeyWorker(&ibutton_gpio)); | ||||||
|  |     bool exit = false; | ||||||
|  |     string_t data; | ||||||
|  |     string_init(data); | ||||||
|  | 
 | ||||||
|  |     if(!args_read_string_and_trim(args, data)) { | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(!ibutton_cli_get_key_type(data, &type)) { | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     key.set_type(type); | ||||||
|  | 
 | ||||||
|  |     if(!args_read_hex_bytes(args, key.get_data(), key.get_type_data_size())) { | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("Emulating key "); | ||||||
|  |     ibutton_cli_print_key_data(&key); | ||||||
|  |     printf("Press Ctrl+C to abort\r\n"); | ||||||
|  | 
 | ||||||
|  |     worker->start_emulate(&key); | ||||||
|  | 
 | ||||||
|  |     while(!exit) { | ||||||
|  |         exit = cli_cmd_interrupt_received(cli); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     worker->stop_emulate(); | ||||||
|  | 
 | ||||||
|  |     string_clear(data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void ibutton_cli(Cli* cli, string_t args, void* context) { | ||||||
|  |     string_t cmd; | ||||||
|  |     string_init(cmd); | ||||||
|  | 
 | ||||||
|  |     if(!args_read_string_and_trim(args, cmd)) { | ||||||
|  |         string_clear(cmd); | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(string_cmp_str(cmd, "read") == 0) { | ||||||
|  |         ibutton_cli_read(cli); | ||||||
|  |     } else if(string_cmp_str(cmd, "write") == 0) { | ||||||
|  |         ibutton_cli_write(cli, args); | ||||||
|  |     } else if(string_cmp_str(cmd, "emulate") == 0) { | ||||||
|  |         ibutton_cli_emulate(cli, args); | ||||||
|  |     } else { | ||||||
|  |         ibutton_cli_print_usage(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     string_clear(cmd); | ||||||
|  | } | ||||||
| @ -1,102 +0,0 @@ | |||||||
| #include "ibutton-scene-cli-emulate.h" |  | ||||||
| #include "../ibutton-app.h" |  | ||||||
| #include "../ibutton-view-manager.h" |  | ||||||
| #include "../ibutton-event.h" |  | ||||||
| #include "../ibutton-key.h" |  | ||||||
| #include <callback-connector.h> |  | ||||||
| 
 |  | ||||||
| void iButtonSceneCliEmulate::on_enter(iButtonApp* app) { |  | ||||||
|     iButtonAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     iButtonKey* key = app->get_key(); |  | ||||||
|     uint8_t* key_data = key->get_data(); |  | ||||||
|     const char* key_name = key->get_name(); |  | ||||||
|     uint8_t line_count = 2; |  | ||||||
|     timeout = 50; // 5s timeout
 |  | ||||||
| 
 |  | ||||||
|     // check that stored key has name
 |  | ||||||
|     if(strcmp(key_name, "") != 0) { |  | ||||||
|         app->set_text_store("emulating\n%s", key_name); |  | ||||||
|         line_count = 2; |  | ||||||
|     } else { |  | ||||||
|         // if not, show key data
 |  | ||||||
|         switch(key->get_key_type()) { |  | ||||||
|         case iButtonKeyType::KeyDallas: |  | ||||||
|             app->set_text_store( |  | ||||||
|                 "emulating\n%02X %02X %02X %02X\n%02X %02X %02X %02X", |  | ||||||
|                 key_data[0], |  | ||||||
|                 key_data[1], |  | ||||||
|                 key_data[2], |  | ||||||
|                 key_data[3], |  | ||||||
|                 key_data[4], |  | ||||||
|                 key_data[5], |  | ||||||
|                 key_data[6], |  | ||||||
|                 key_data[7]); |  | ||||||
|             line_count = 3; |  | ||||||
|             break; |  | ||||||
|         case iButtonKeyType::KeyCyfral: |  | ||||||
|             app->set_text_store("emulating\n%02X %02X", key_data[0], key_data[1]); |  | ||||||
|             line_count = 2; |  | ||||||
|             break; |  | ||||||
|         case iButtonKeyType::KeyMetakom: |  | ||||||
|             app->set_text_store( |  | ||||||
|                 "emulating\n%02X %02X %02X %02X", |  | ||||||
|                 key_data[0], |  | ||||||
|                 key_data[1], |  | ||||||
|                 key_data[2], |  | ||||||
|                 key_data[3]); |  | ||||||
|             line_count = 2; |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     switch(line_count) { |  | ||||||
|     case 3: |  | ||||||
|         popup_set_header(popup, "iButton", 92, 18, AlignCenter, AlignBottom); |  | ||||||
|         popup_set_text(popup, app->get_text_store(), 92, 22, AlignCenter, AlignTop); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     default: |  | ||||||
|         popup_set_header(popup, "iButton", 92, 24, AlignCenter, AlignBottom); |  | ||||||
|         popup_set_text(popup, app->get_text_store(), 92, 28, AlignCenter, AlignTop); |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     popup_set_icon(popup, 10, 10, I_iButtonKey_49x44); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); |  | ||||||
|     app->get_key_worker()->start_emulate(app->get_key()); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool iButtonSceneCliEmulate::on_event(iButtonApp* app, iButtonEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     if(event->type == iButtonEvent::Type::EventTypeTick) { |  | ||||||
|         consumed = true; |  | ||||||
|         if(!timeout--) { |  | ||||||
|             app->cli_send_event(iButtonApp::CliEvent::CliTimeout); |  | ||||||
|             app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|         } else { |  | ||||||
|             if(app->get_key_worker()->emulated()) { |  | ||||||
|                 app->notify_yellow_blink(); |  | ||||||
|             } else { |  | ||||||
|                 app->notify_red_blink(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } else if(event->type == iButtonEvent::Type::EventTypeBack) { |  | ||||||
|         consumed = false; |  | ||||||
|         app->cli_send_event(iButtonApp::CliEvent::CliInterrupt); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void iButtonSceneCliEmulate::on_exit(iButtonApp* app) { |  | ||||||
|     app->get_key_worker()->stop_emulate(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = app->get_view_manager()->get_popup(); |  | ||||||
| 
 |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "ibutton-scene-generic.h" |  | ||||||
| #include "../helpers/key-emulator.h" |  | ||||||
| 
 |  | ||||||
| class iButtonSceneCliEmulate : public iButtonScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(iButtonApp* app) final; |  | ||||||
|     bool on_event(iButtonApp* app, iButtonEvent* event) final; |  | ||||||
|     void on_exit(iButtonApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     uint16_t timeout; |  | ||||||
| }; |  | ||||||
| @ -1,65 +0,0 @@ | |||||||
| #include "ibutton-scene-cli-read.h" |  | ||||||
| #include "../ibutton-app.h" |  | ||||||
| #include "../ibutton-view-manager.h" |  | ||||||
| #include "../ibutton-event.h" |  | ||||||
| 
 |  | ||||||
| void iButtonSceneCliRead::on_enter(iButtonApp* app) { |  | ||||||
|     iButtonAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     timeout = 50; // 5s timeout
 |  | ||||||
| 
 |  | ||||||
|     popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, "waiting\nfor key ...", 95, 30, AlignCenter, AlignTop); |  | ||||||
|     popup_set_icon(popup, 0, 5, I_DolphinWait_61x59); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); |  | ||||||
|     app->get_key()->set_name(""); |  | ||||||
| 
 |  | ||||||
|     app->get_key_worker()->start_read(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool iButtonSceneCliRead::on_event(iButtonApp* app, iButtonEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     if(event->type == iButtonEvent::Type::EventTypeTick) { |  | ||||||
|         consumed = true; |  | ||||||
|         app->notify_red_blink(); |  | ||||||
|         if(!timeout--) { |  | ||||||
|             app->cli_send_event(iButtonApp::CliEvent::CliTimeout); |  | ||||||
|             app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|             return consumed; |  | ||||||
|         } else { |  | ||||||
|             switch(app->get_key_worker()->read(app->get_key())) { |  | ||||||
|             case KeyReader::Error::EMPTY: |  | ||||||
|                 break; |  | ||||||
|             case KeyReader::Error::OK: |  | ||||||
|                 app->cli_send_event(iButtonApp::CliEvent::CliReadSuccess); |  | ||||||
|                 app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|                 break; |  | ||||||
|             case KeyReader::Error::CRC_ERROR: |  | ||||||
|                 app->cli_send_event(iButtonApp::CliEvent::CliReadCRCError); |  | ||||||
|                 app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|                 break; |  | ||||||
|             case KeyReader::Error::NOT_ARE_KEY: |  | ||||||
|                 app->cli_send_event(iButtonApp::CliEvent::CliReadNotKeyError); |  | ||||||
|                 app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } else if(event->type == iButtonEvent::Type::EventTypeBack) { |  | ||||||
|         consumed = false; |  | ||||||
|         app->cli_send_event(iButtonApp::CliEvent::CliInterrupt); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void iButtonSceneCliRead::on_exit(iButtonApp* app) { |  | ||||||
|     app->get_key_worker()->stop_read(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = app->get_view_manager()->get_popup(); |  | ||||||
| 
 |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |  | ||||||
| } |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "ibutton-scene-generic.h" |  | ||||||
| 
 |  | ||||||
| class iButtonSceneCliRead : public iButtonScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(iButtonApp* app) final; |  | ||||||
|     bool on_event(iButtonApp* app, iButtonEvent* event) final; |  | ||||||
|     void on_exit(iButtonApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     uint16_t timeout; |  | ||||||
| }; |  | ||||||
| @ -1,109 +0,0 @@ | |||||||
| #include "ibutton-scene-cli-write.h" |  | ||||||
| #include "../ibutton-app.h" |  | ||||||
| #include "../ibutton-view-manager.h" |  | ||||||
| #include "../ibutton-event.h" |  | ||||||
| #include "../ibutton-key.h" |  | ||||||
| 
 |  | ||||||
| void iButtonSceneCliWrite::on_enter(iButtonApp* app) { |  | ||||||
|     iButtonAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     iButtonKey* key = app->get_key(); |  | ||||||
|     uint8_t* key_data = key->get_data(); |  | ||||||
|     const char* key_name = key->get_name(); |  | ||||||
|     uint8_t line_count = 2; |  | ||||||
|     timeout = 50; // 5s timeout
 |  | ||||||
| 
 |  | ||||||
|     // check that stored key has name
 |  | ||||||
|     if(strcmp(key_name, "") != 0) { |  | ||||||
|         app->set_text_store("writing\n%s", key_name); |  | ||||||
|         line_count = 2; |  | ||||||
|     } else { |  | ||||||
|         // if not, show key data
 |  | ||||||
|         switch(key->get_key_type()) { |  | ||||||
|         case iButtonKeyType::KeyDallas: |  | ||||||
|             app->set_text_store( |  | ||||||
|                 "writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X", |  | ||||||
|                 key_data[0], |  | ||||||
|                 key_data[1], |  | ||||||
|                 key_data[2], |  | ||||||
|                 key_data[3], |  | ||||||
|                 key_data[4], |  | ||||||
|                 key_data[5], |  | ||||||
|                 key_data[6], |  | ||||||
|                 key_data[7]); |  | ||||||
|             line_count = 3; |  | ||||||
|             break; |  | ||||||
|         case iButtonKeyType::KeyCyfral: |  | ||||||
|             app->set_text_store("writing\n%02X %02X", key_data[0], key_data[1]); |  | ||||||
|             line_count = 2; |  | ||||||
|             break; |  | ||||||
|         case iButtonKeyType::KeyMetakom: |  | ||||||
|             app->set_text_store( |  | ||||||
|                 "writing\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); |  | ||||||
|             line_count = 2; |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     switch(line_count) { |  | ||||||
|     case 3: |  | ||||||
|         popup_set_header(popup, "iButton", 92, 18, AlignCenter, AlignBottom); |  | ||||||
|         popup_set_text(popup, app->get_text_store(), 92, 22, AlignCenter, AlignTop); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     default: |  | ||||||
|         popup_set_header(popup, "iButton", 92, 24, AlignCenter, AlignBottom); |  | ||||||
|         popup_set_text(popup, app->get_text_store(), 92, 28, AlignCenter, AlignTop); |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     popup_set_icon(popup, 10, 10, I_iButtonKey_49x44); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); |  | ||||||
| 
 |  | ||||||
|     app->get_key_worker()->start_write(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool iButtonSceneCliWrite::on_event(iButtonApp* app, iButtonEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     if(event->type == iButtonEvent::Type::EventTypeTick) { |  | ||||||
|         consumed = true; |  | ||||||
|         if(!timeout--) { |  | ||||||
|             app->cli_send_event(iButtonApp::CliEvent::CliTimeout); |  | ||||||
|             app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|         } else { |  | ||||||
|             KeyWriter::Error result = app->get_key_worker()->write(app->get_key()); |  | ||||||
| 
 |  | ||||||
|             switch(result) { |  | ||||||
|             case KeyWriter::Error::SAME_KEY: |  | ||||||
|             case KeyWriter::Error::OK: |  | ||||||
|                 app->cli_send_event(iButtonApp::CliEvent::CliWriteSuccess); |  | ||||||
|                 app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|                 break; |  | ||||||
|             case KeyWriter::Error::NO_DETECT: |  | ||||||
|                 app->notify_red_blink(); |  | ||||||
|                 break; |  | ||||||
|             case KeyWriter::Error::CANNOT_WRITE: |  | ||||||
|                 app->cli_send_event(iButtonApp::CliEvent::CliWriteFail); |  | ||||||
|                 app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } else if(event->type == iButtonEvent::Type::EventTypeBack) { |  | ||||||
|         consumed = false; |  | ||||||
|         app->cli_send_event(iButtonApp::CliEvent::CliInterrupt); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void iButtonSceneCliWrite::on_exit(iButtonApp* app) { |  | ||||||
|     Popup* popup = app->get_view_manager()->get_popup(); |  | ||||||
| 
 |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |  | ||||||
| 
 |  | ||||||
|     app->get_key_worker()->stop_write(); |  | ||||||
| } |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "ibutton-scene-generic.h" |  | ||||||
| 
 |  | ||||||
| class iButtonSceneCliWrite : public iButtonScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(iButtonApp* app) final; |  | ||||||
|     bool on_event(iButtonApp* app, iButtonEvent* event) final; |  | ||||||
|     void on_exit(iButtonApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     uint16_t timeout; |  | ||||||
| }; |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG