[FL-1063} LF-RFID Cli (#515)
* App lfrfid: update emulator to process external data. * App lfrfid: cleanup emulator * App lfrfid: cli interface * Lib: arguments parser lib Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									ced7d6315d
								
							
						
					
					
						commit
						4ad5245969
					
				| @ -45,6 +45,7 @@ void irda_cli_init(); | |||||||
| void nfc_cli_init(); | void nfc_cli_init(); | ||||||
| void subghz_cli_init(); | void subghz_cli_init(); | ||||||
| void bt_cli_init(); | void bt_cli_init(); | ||||||
|  | void lfrfid_cli_init(); | ||||||
| 
 | 
 | ||||||
| const FlipperApplication FLIPPER_SERVICES[] = { | const FlipperApplication FLIPPER_SERVICES[] = { | ||||||
| #ifdef SRV_CLI | #ifdef SRV_CLI | ||||||
| @ -211,6 +212,9 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | |||||||
| #ifdef APP_SUBGHZ | #ifdef APP_SUBGHZ | ||||||
|     subghz_cli_init, |     subghz_cli_init, | ||||||
| #endif | #endif | ||||||
|  | #ifdef APP_LF_RFID | ||||||
|  |     lfrfid_cli_init, | ||||||
|  | #endif | ||||||
| #ifdef SRV_BT | #ifdef SRV_BT | ||||||
|     bt_cli_init, |     bt_cli_init, | ||||||
| #endif | #endif | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								applications/lf-rfid/helpers/key-info.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								applications/lf-rfid/helpers/key-info.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | #include "key-info.h" | ||||||
|  | 
 | ||||||
|  | const char* lfrfid_key_get_type_string(LfrfidKeyType type) { | ||||||
|  |     switch(type) { | ||||||
|  |     case LfrfidKeyType::KeyEM4100: | ||||||
|  |         return "EM4100"; | ||||||
|  |         break; | ||||||
|  |     case LfrfidKeyType::KeyH10301: | ||||||
|  |         return "H10301"; | ||||||
|  |         break; | ||||||
|  |     case LfrfidKeyType::KeyI40134: | ||||||
|  |         return "I40134"; | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return "Unknown"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t lfrfid_key_get_type_data_count(LfrfidKeyType type) { | ||||||
|  |     switch(type) { | ||||||
|  |     case LfrfidKeyType::KeyEM4100: | ||||||
|  |         return 5; | ||||||
|  |         break; | ||||||
|  |     case LfrfidKeyType::KeyH10301: | ||||||
|  |         return 3; | ||||||
|  |         break; | ||||||
|  |     case LfrfidKeyType::KeyI40134: | ||||||
|  |         return 3; | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
| @ -4,7 +4,10 @@ | |||||||
| static const uint8_t LFRFID_KEY_SIZE = 8; | static const uint8_t LFRFID_KEY_SIZE = 8; | ||||||
| 
 | 
 | ||||||
| enum class LfrfidKeyType : uint8_t { | enum class LfrfidKeyType : uint8_t { | ||||||
|     KeyEmarine, |     KeyEM4100, | ||||||
|     KeyHID, |     KeyH10301, | ||||||
|     KeyIndala, |     KeyI40134, | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | const char* lfrfid_key_get_type_string(LfrfidKeyType type); | ||||||
|  | uint8_t lfrfid_key_get_type_data_count(LfrfidKeyType type); | ||||||
| @ -71,12 +71,12 @@ bool RfidReader::read(LfrfidKeyType* type, uint8_t* data, uint8_t data_size) { | |||||||
|     bool result = false; |     bool result = false; | ||||||
| 
 | 
 | ||||||
|     if(decoder_em.read(data, data_size)) { |     if(decoder_em.read(data, data_size)) { | ||||||
|         *type = LfrfidKeyType::KeyEmarine; |         *type = LfrfidKeyType::KeyEM4100; | ||||||
|         result = true; |         result = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(decoder_hid26.read(data, data_size)) { |     if(decoder_hid26.read(data, data_size)) { | ||||||
|         *type = LfrfidKeyType::KeyHID; |         *type = LfrfidKeyType::KeyH10301; | ||||||
|         result = true; |         result = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ RfidTimerEmulator::RfidTimerEmulator() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RfidTimerEmulator::~RfidTimerEmulator() { | RfidTimerEmulator::~RfidTimerEmulator() { | ||||||
|     std::map<Type, EncoderGeneric*>::iterator it; |     std::map<LfrfidKeyType, EncoderGeneric*>::iterator it; | ||||||
| 
 | 
 | ||||||
|     for(it = encoders.begin(); it != encoders.end(); ++it) { |     for(it = encoders.begin(); it != encoders.end(); ++it) { | ||||||
|         delete it->second; |         delete it->second; | ||||||
| @ -14,30 +14,19 @@ RfidTimerEmulator::~RfidTimerEmulator() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RfidTimerEmulator::start(Type type) { | void RfidTimerEmulator::start(LfrfidKeyType type, const uint8_t* data, uint8_t data_size) { | ||||||
|     if(encoders.count(type)) { |     if(encoders.count(type)) { | ||||||
|         current_encoder = encoders.find(type)->second; |         current_encoder = encoders.find(type)->second; | ||||||
|         uint8_t em_data[5] = {0x53, 0x00, 0x5F, 0xB3, 0xC2}; |  | ||||||
|         uint8_t hid_data[3] = {0xED, 0x87, 0x70}; |  | ||||||
|         uint8_t indala_data[3] = {0x1F, 0x2E, 0x3D}; |  | ||||||
| 
 | 
 | ||||||
|         switch(type) { |         if(lfrfid_key_get_type_data_count(type) == data_size) { | ||||||
|         case Type::EM: |             current_encoder->init(data, data_size); | ||||||
|             current_encoder->init(em_data, 5); |  | ||||||
|             break; |  | ||||||
|         case Type::HID_H10301: |  | ||||||
|             current_encoder->init(hid_data, 3); |  | ||||||
|             break; |  | ||||||
|         case Type::Indala_40134: |  | ||||||
|             current_encoder->init(indala_data, 3); |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|             api_hal_rfid_tim_emulate(125000); |             api_hal_rfid_tim_emulate(125000); | ||||||
|             api_hal_rfid_pins_emulate(); |             api_hal_rfid_pins_emulate(); | ||||||
| 
 | 
 | ||||||
|             api_interrupt_add(timer_update_callback, InterruptTypeTimerUpdate, this); |             api_interrupt_add(timer_update_callback, InterruptTypeTimerUpdate, this); | ||||||
| 
 | 
 | ||||||
|  |             // TODO make api for interrupts priority
 | ||||||
|             for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { |             for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { | ||||||
|                 HAL_NVIC_SetPriority(static_cast<IRQn_Type>(i), 15, 0); |                 HAL_NVIC_SetPriority(static_cast<IRQn_Type>(i), 15, 0); | ||||||
|             } |             } | ||||||
| @ -46,6 +35,7 @@ void RfidTimerEmulator::start(Type type) { | |||||||
|             HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); |             HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); | ||||||
| 
 | 
 | ||||||
|             api_hal_rfid_tim_emulate_start(); |             api_hal_rfid_tim_emulate_start(); | ||||||
|  |         } | ||||||
|     } else { |     } else { | ||||||
|         // not found
 |         // not found
 | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -10,24 +10,18 @@ | |||||||
| 
 | 
 | ||||||
| class RfidTimerEmulator { | class RfidTimerEmulator { | ||||||
| public: | public: | ||||||
|     enum class Type : uint8_t { |  | ||||||
|         EM, |  | ||||||
|         HID_H10301, |  | ||||||
|         Indala_40134, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     RfidTimerEmulator(); |     RfidTimerEmulator(); | ||||||
|     ~RfidTimerEmulator(); |     ~RfidTimerEmulator(); | ||||||
|     void start(Type type); |     void start(LfrfidKeyType type, const uint8_t* data, uint8_t data_size); | ||||||
|     void stop(); |     void stop(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     EncoderGeneric* current_encoder = nullptr; |     EncoderGeneric* current_encoder = nullptr; | ||||||
| 
 | 
 | ||||||
|     std::map<Type, EncoderGeneric*> encoders = { |     std::map<LfrfidKeyType, EncoderGeneric*> encoders = { | ||||||
|         {Type::EM, new EncoderEM()}, |         {LfrfidKeyType::KeyEM4100, new EncoderEM()}, | ||||||
|         {Type::HID_H10301, new EncoderHID_H10301()}, |         {LfrfidKeyType::KeyH10301, new EncoderHID_H10301()}, | ||||||
|         {Type::Indala_40134, new EncoderIndala_40134()}, |         {LfrfidKeyType::KeyI40134, new EncoderIndala_40134()}, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     PulseJoiner pulse_joiner; |     PulseJoiner pulse_joiner; | ||||||
|  | |||||||
							
								
								
									
										142
									
								
								applications/lf-rfid/lf-rfid-cli.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								applications/lf-rfid/lf-rfid-cli.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | #include <furi.h> | ||||||
|  | #include <api-hal.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <cli/cli.h> | ||||||
|  | #include <args.h> | ||||||
|  | 
 | ||||||
|  | #include "helpers/rfid-reader.h" | ||||||
|  | #include "helpers/rfid-timer-emulator.h" | ||||||
|  | 
 | ||||||
|  | void lfrfid_cli(Cli* cli, string_t args, void* context); | ||||||
|  | 
 | ||||||
|  | // app cli function
 | ||||||
|  | extern "C" void lfrfid_cli_init() { | ||||||
|  |     Cli* cli = static_cast<Cli*>(furi_record_open("cli")); | ||||||
|  |     cli_add_command(cli, "rfid", lfrfid_cli, NULL); | ||||||
|  |     furi_record_close("cli"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lfrfid_cli_print_usage() { | ||||||
|  |     printf("Usage:\r\n"); | ||||||
|  |     printf("rfid read\r\n"); | ||||||
|  |     printf("rfid <write | emulate> <key_type> <key_data>\r\n"); | ||||||
|  |     printf("\t<key_type> choose from:\r\n"); | ||||||
|  |     printf("\tEM4100, EM-Marin (5 bytes key_data)\r\n"); | ||||||
|  |     printf("\tH10301, HID26 (3 bytes key_data)\r\n"); | ||||||
|  |     printf("\tI40134, Indala (3 bytes key_data)\r\n"); | ||||||
|  |     printf("\t<key_data> are hex-formatted\r\n"); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | bool lfrfid_cli_get_key_type(string_t data, LfrfidKeyType* type) { | ||||||
|  |     bool result = false; | ||||||
|  | 
 | ||||||
|  |     if(string_cmp_str(data, "EM4100") == 0 || string_cmp_str(data, "EM-Marin") == 0) { | ||||||
|  |         result = true; | ||||||
|  |         *type = LfrfidKeyType::KeyEM4100; | ||||||
|  |     } else if(string_cmp_str(data, "H10301") == 0 || string_cmp_str(data, "HID26") == 0) { | ||||||
|  |         result = true; | ||||||
|  |         *type = LfrfidKeyType::KeyH10301; | ||||||
|  |     } else if(string_cmp_str(data, "I40134") == 0 || string_cmp_str(data, "Indala") == 0) { | ||||||
|  |         result = true; | ||||||
|  |         *type = LfrfidKeyType::KeyI40134; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lfrfid_cli_read(Cli* cli) { | ||||||
|  |     RfidReader reader; | ||||||
|  |     reader.start(RfidReader::Type::Normal); | ||||||
|  | 
 | ||||||
|  |     static const uint8_t data_size = LFRFID_KEY_SIZE; | ||||||
|  |     uint8_t data[data_size] = {0}; | ||||||
|  |     LfrfidKeyType type; | ||||||
|  | 
 | ||||||
|  |     printf("Reading RFID...\r\nPress Ctrl+C to abort\r\n"); | ||||||
|  |     while(!cli_cmd_interrupt_received(cli)) { | ||||||
|  |         if(reader.read(&type, data, data_size)) { | ||||||
|  |             printf(lfrfid_key_get_type_string(type)); | ||||||
|  |             printf(" "); | ||||||
|  | 
 | ||||||
|  |             for(uint8_t i = 0; i < lfrfid_key_get_type_data_count(type); i++) { | ||||||
|  |                 printf("%02X", data[i]); | ||||||
|  |             } | ||||||
|  |             printf("\r\n"); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         delay(100); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("Reading stopped\r\n"); | ||||||
|  |     reader.stop(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lfrfid_cli_write(Cli* cli, string_t args) { | ||||||
|  |     // TODO implement rfid write
 | ||||||
|  |     printf("Not implemented :(\r\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lfrfid_cli_emulate(Cli* cli, string_t args) { | ||||||
|  |     string_t data; | ||||||
|  |     string_init(data); | ||||||
|  |     RfidTimerEmulator emulator; | ||||||
|  | 
 | ||||||
|  |     static const uint8_t data_size = LFRFID_KEY_SIZE; | ||||||
|  |     uint8_t key_data[data_size] = {0}; | ||||||
|  |     uint8_t key_data_size = 0; | ||||||
|  |     LfrfidKeyType type; | ||||||
|  | 
 | ||||||
|  |     if(!args_read_string_and_trim(args, data)) { | ||||||
|  |         lfrfid_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(!lfrfid_cli_get_key_type(data, &type)) { | ||||||
|  |         lfrfid_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     key_data_size = lfrfid_key_get_type_data_count(type); | ||||||
|  | 
 | ||||||
|  |     if(!args_read_hex_bytes(args, key_data, key_data_size)) { | ||||||
|  |         lfrfid_cli_print_usage(); | ||||||
|  |         string_clear(data); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     emulator.start(type, key_data, key_data_size); | ||||||
|  | 
 | ||||||
|  |     printf("Emulating RFID...\r\nPress Ctrl+C to abort\r\n"); | ||||||
|  |     while(!cli_cmd_interrupt_received(cli)) { | ||||||
|  |         delay(100); | ||||||
|  |     } | ||||||
|  |     printf("Emulation stopped\r\n"); | ||||||
|  |     emulator.stop(); | ||||||
|  | 
 | ||||||
|  |     string_clear(data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lfrfid_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); | ||||||
|  |         lfrfid_cli_print_usage(); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(string_cmp_str(cmd, "read") == 0) { | ||||||
|  |         lfrfid_cli_read(cli); | ||||||
|  |     } else if(string_cmp_str(cmd, "write") == 0) { | ||||||
|  |         lfrfid_cli_write(cli, args); | ||||||
|  |     } else if(string_cmp_str(cmd, "emulate") == 0) { | ||||||
|  |         lfrfid_cli_emulate(cli, args); | ||||||
|  |     } else { | ||||||
|  |         lfrfid_cli_print_usage(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     string_clear(cmd); | ||||||
|  | } | ||||||
| @ -14,7 +14,7 @@ void LfrfidSceneEmulateEMMarine::on_enter(LfrfidApp* app) { | |||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); | ||||||
|     app->get_emulator()->start(RfidTimerEmulator::Type::EM); |     app->get_emulator()->start(LfrfidKeyType::KeyEM4100, data, 5); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LfrfidSceneEmulateEMMarine::on_event(LfrfidApp* app, LfrfidEvent* event) { | bool LfrfidSceneEmulateEMMarine::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||||
|  | |||||||
| @ -9,4 +9,5 @@ public: | |||||||
|     void on_exit(LfrfidApp* app) final; |     void on_exit(LfrfidApp* app) final; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |     const uint8_t data[5] = {0x53, 0x00, 0x5F, 0xB3, 0xC2}; | ||||||
| }; | }; | ||||||
| @ -14,7 +14,7 @@ void LfrfidSceneEmulateHID::on_enter(LfrfidApp* app) { | |||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); | ||||||
|     app->get_emulator()->start(RfidTimerEmulator::Type::HID_H10301); |     app->get_emulator()->start(LfrfidKeyType::KeyH10301, data, 3); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LfrfidSceneEmulateHID::on_event(LfrfidApp* app, LfrfidEvent* event) { | bool LfrfidSceneEmulateHID::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||||
|  | |||||||
| @ -9,4 +9,5 @@ public: | |||||||
|     void on_exit(LfrfidApp* app) final; |     void on_exit(LfrfidApp* app) final; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |     const uint8_t data[3] = {0xED, 0x87, 0x70}; | ||||||
| }; | }; | ||||||
| @ -14,7 +14,7 @@ void LfrfidSceneEmulateIndala::on_enter(LfrfidApp* app) { | |||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); | ||||||
|     app->get_emulator()->start(RfidTimerEmulator::Type::Indala_40134); |     app->get_emulator()->start(LfrfidKeyType::KeyI40134, data, 3); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LfrfidSceneEmulateIndala::on_event(LfrfidApp* app, LfrfidEvent* event) { | bool LfrfidSceneEmulateIndala::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||||
|  | |||||||
| @ -9,4 +9,5 @@ public: | |||||||
|     void on_exit(LfrfidApp* app) final; |     void on_exit(LfrfidApp* app) final; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |     const uint8_t data[3] = {0x1F, 0x2E, 0x3D}; | ||||||
| }; | }; | ||||||
| @ -35,7 +35,7 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             switch(type) { |             switch(type) { | ||||||
|             case LfrfidKeyType::KeyEmarine: |             case LfrfidKeyType::KeyEM4100: | ||||||
|                 app->set_text_store( |                 app->set_text_store( | ||||||
|                     "[EM] %02X %02X %02X %02X %02X\n" |                     "[EM] %02X %02X %02X %02X %02X\n" | ||||||
|                     "count: %u", |                     "count: %u", | ||||||
| @ -46,7 +46,7 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { | |||||||
|                     data[4], |                     data[4], | ||||||
|                     success_reads); |                     success_reads); | ||||||
|                 break; |                 break; | ||||||
|             case LfrfidKeyType::KeyHID: |             case LfrfidKeyType::KeyH10301: | ||||||
|                 app->set_text_store( |                 app->set_text_store( | ||||||
|                     "[HID26] %02X %02X %02X\n" |                     "[HID26] %02X %02X %02X\n" | ||||||
|                     "count: %u", |                     "count: %u", | ||||||
| @ -55,7 +55,7 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { | |||||||
|                     data[2], |                     data[2], | ||||||
|                     success_reads); |                     success_reads); | ||||||
|                 break; |                 break; | ||||||
|             case LfrfidKeyType::KeyIndala: |             case LfrfidKeyType::KeyI40134: | ||||||
|                 app->set_text_store( |                 app->set_text_store( | ||||||
|                     "[IND] %02X %02X %02X\n" |                     "[IND] %02X %02X %02X\n" | ||||||
|                     "count: %u", |                     "count: %u", | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ bool LfrfidSceneWrite::on_event(LfrfidApp* app, LfrfidEvent* event) { | |||||||
|         LfrfidKeyType type; |         LfrfidKeyType type; | ||||||
| 
 | 
 | ||||||
|         app->get_reader()->read(&type, data, LFRFID_KEY_SIZE); |         app->get_reader()->read(&type, data, LFRFID_KEY_SIZE); | ||||||
|         if(type == LfrfidKeyType::KeyEmarine) { |         if(type == LfrfidKeyType::KeyEM4100) { | ||||||
|             if(memcmp(em_data, data, 5) == 0) { |             if(memcmp(em_data, data, 5) == 0) { | ||||||
|                 readed = true; |                 readed = true; | ||||||
|             } |             } | ||||||
|  | |||||||
							
								
								
									
										76
									
								
								lib/args/args.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								lib/args/args.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | |||||||
|  | #include "args.h" | ||||||
|  | 
 | ||||||
|  | size_t args_get_first_word_length(string_t args) { | ||||||
|  |     size_t ws = string_search_char(args, ' '); | ||||||
|  |     if(ws == STRING_FAILURE) { | ||||||
|  |         ws = strlen(string_get_cstr(args)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ws; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | size_t args_length(string_t args) { | ||||||
|  |     return strlen(string_get_cstr(args)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool args_read_string_and_trim(string_t args, string_t word) { | ||||||
|  |     size_t cmd_length = args_get_first_word_length(args); | ||||||
|  | 
 | ||||||
|  |     if(cmd_length == 0) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     string_set_n(word, args, 0, cmd_length); | ||||||
|  |     string_right(args, cmd_length); | ||||||
|  |     string_strim(args); | ||||||
|  | 
 | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool args_char_to_hex_nibble(char c, uint8_t* nibble) { | ||||||
|  |     if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) { | ||||||
|  |         if((c >= '0' && c <= '9')) { | ||||||
|  |             *nibble = c - '0'; | ||||||
|  |         } else if((c >= 'A' && c <= 'F')) { | ||||||
|  |             *nibble = c - 'A' + 10; | ||||||
|  |         } else { | ||||||
|  |             *nibble = c - 'a' + 10; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } else { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool args_char_to_hex(char hi_nibble, char low_nibble, uint8_t* byte) { | ||||||
|  |     uint8_t hi_nibble_value = 0; | ||||||
|  |     uint8_t low_nibble_value = 0; | ||||||
|  |     bool result = false; | ||||||
|  | 
 | ||||||
|  |     if(args_char_to_hex_nibble(hi_nibble, &hi_nibble_value)) { | ||||||
|  |         if(args_char_to_hex_nibble(low_nibble, &low_nibble_value)) { | ||||||
|  |             result = true; | ||||||
|  |             *byte = (hi_nibble_value << 4) | low_nibble_value; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool args_read_hex_bytes(string_t args, uint8_t* bytes, uint8_t bytes_count) { | ||||||
|  |     bool result = true; | ||||||
|  |     const char* str_pointer = string_get_cstr(args); | ||||||
|  | 
 | ||||||
|  |     if(args_get_first_word_length(args) == (bytes_count * 2)) { | ||||||
|  |         for(uint8_t i = 0; i < bytes_count; i++) { | ||||||
|  |             if(!args_char_to_hex(str_pointer[i * 2], str_pointer[i * 2 + 1], &(bytes[i]))) { | ||||||
|  |                 result = false; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         result = false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								lib/args/args.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								lib/args/args.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "m-string.h" | ||||||
|  | #include "stdint.h" | ||||||
|  | #include "stdbool.h" | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Extract first word from arguments string and trim arguments string | ||||||
|  |  *  | ||||||
|  |  * @param args arguments string | ||||||
|  |  * @param word first word, output | ||||||
|  |  * @return true - success | ||||||
|  |  * @return false - arguments string does not contain anything | ||||||
|  |  */ | ||||||
|  | bool args_read_string_and_trim(string_t args, string_t word); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Convert hex ASCII values to byte array | ||||||
|  |  *  | ||||||
|  |  * @param args arguments string | ||||||
|  |  * @param bytes byte array pointer, output | ||||||
|  |  * @param bytes_count needed bytes count | ||||||
|  |  * @return true - success | ||||||
|  |  * @return false - arguments string does not contain enough values, or contain non-hex ASCII values | ||||||
|  |  */ | ||||||
|  | bool args_read_hex_bytes(string_t args, uint8_t* bytes, uint8_t bytes_count); | ||||||
|  | 
 | ||||||
|  | /************************************ HELPERS ***************************************/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Get length of first word from arguments string | ||||||
|  |  *  | ||||||
|  |  * @param args arguments string | ||||||
|  |  * @return size_t length of first word | ||||||
|  |  */ | ||||||
|  | size_t args_get_first_word_length(string_t args); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Get length of arguments string | ||||||
|  |  *  | ||||||
|  |  * @param args arguments string | ||||||
|  |  * @return size_t length of arguments string | ||||||
|  |  */ | ||||||
|  | size_t args_length(string_t args); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Convert ASCII hex value to nibble  | ||||||
|  |  *  | ||||||
|  |  * @param c ASCII character | ||||||
|  |  * @param nibble nibble pointer, output | ||||||
|  |  * @return bool conversion status | ||||||
|  |  */ | ||||||
|  | bool args_char_to_hex_nibble(char c, uint8_t* nibble); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Convert ASCII hex values to byte | ||||||
|  |  *  | ||||||
|  |  * @param hi_nibble ASCII hi nibble character | ||||||
|  |  * @param low_nibble ASCII low nibble character | ||||||
|  |  * @param byte byte pointer, output | ||||||
|  |  * @return bool conversion status | ||||||
|  |  */ | ||||||
|  | bool args_char_to_hex(char hi_nibble, char low_nibble, uint8_t* byte); | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
							
								
								
									
										14
									
								
								lib/lib.mk
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								lib/lib.mk
									
									
									
									
									
								
							| @ -66,15 +66,6 @@ CFLAGS			+= -I$(LIB_DIR)/app-template | |||||||
| CFLAGS			+= -I$(LIB_DIR)/fnv1a-hash | CFLAGS			+= -I$(LIB_DIR)/fnv1a-hash | ||||||
| C_SOURCES		+= $(LIB_DIR)/fnv1a-hash/fnv1a-hash.c | C_SOURCES		+= $(LIB_DIR)/fnv1a-hash/fnv1a-hash.c | ||||||
| 
 | 
 | ||||||
| # build onewire/cyfral library only if
 |  | ||||||
| # we build iButton application
 |  | ||||||
| ifeq ($(APP_IBUTTON), 1) |  | ||||||
| # onewire library
 |  | ||||||
| APP_ONEWIRE	= 1 |  | ||||||
| endif |  | ||||||
| 
 |  | ||||||
| APP_ONEWIRE ?= 0 |  | ||||||
| ifeq ($(APP_ONEWIRE), 1) |  | ||||||
| # onewire library
 | # onewire library
 | ||||||
| ONEWIRE_DIR		= $(LIB_DIR)/onewire | ONEWIRE_DIR		= $(LIB_DIR)/onewire | ||||||
| CFLAGS			+= -I$(ONEWIRE_DIR) | CFLAGS			+= -I$(ONEWIRE_DIR) | ||||||
| @ -84,7 +75,6 @@ CPP_SOURCES		+= $(wildcard $(ONEWIRE_DIR)/*.cpp) | |||||||
| CYFRAL_DIR		= $(LIB_DIR)/cyfral | CYFRAL_DIR		= $(LIB_DIR)/cyfral | ||||||
| CFLAGS			+= -I$(CYFRAL_DIR) | CFLAGS			+= -I$(CYFRAL_DIR) | ||||||
| CPP_SOURCES		+= $(wildcard $(CYFRAL_DIR)/*.cpp) | CPP_SOURCES		+= $(wildcard $(CYFRAL_DIR)/*.cpp) | ||||||
| endif |  | ||||||
| 
 | 
 | ||||||
| # common apps api
 | # common apps api
 | ||||||
| CFLAGS			+= -I$(LIB_DIR)/common-api | CFLAGS			+= -I$(LIB_DIR)/common-api | ||||||
| @ -101,3 +91,7 @@ C_SOURCES		+= $(LIB_DIR)/version/version.c | |||||||
| CFLAGS			+= -I$(LIB_DIR)/irda | CFLAGS			+= -I$(LIB_DIR)/irda | ||||||
| C_SOURCES		+= $(wildcard $(LIB_DIR)/irda/*.c) | C_SOURCES		+= $(wildcard $(LIB_DIR)/irda/*.c) | ||||||
| C_SOURCES		+= $(wildcard $(LIB_DIR)/irda/*/*.c) | C_SOURCES		+= $(wildcard $(LIB_DIR)/irda/*/*.c) | ||||||
|  | 
 | ||||||
|  | #args lib
 | ||||||
|  | CFLAGS			+= -I$(LIB_DIR)/args | ||||||
|  | C_SOURCES		+= $(wildcard $(LIB_DIR)/args/*.c) | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG