[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 subghz_cli_init(); | ||||
| void bt_cli_init(); | ||||
| void lfrfid_cli_init(); | ||||
| 
 | ||||
| const FlipperApplication FLIPPER_SERVICES[] = { | ||||
| #ifdef SRV_CLI | ||||
| @ -211,6 +212,9 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | ||||
| #ifdef APP_SUBGHZ | ||||
|     subghz_cli_init, | ||||
| #endif | ||||
| #ifdef APP_LF_RFID | ||||
|     lfrfid_cli_init, | ||||
| #endif | ||||
| #ifdef SRV_BT | ||||
|     bt_cli_init, | ||||
| #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; | ||||
| 
 | ||||
| enum class LfrfidKeyType : uint8_t { | ||||
|     KeyEmarine, | ||||
|     KeyHID, | ||||
|     KeyIndala, | ||||
| }; | ||||
|     KeyEM4100, | ||||
|     KeyH10301, | ||||
|     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; | ||||
| 
 | ||||
|     if(decoder_em.read(data, data_size)) { | ||||
|         *type = LfrfidKeyType::KeyEmarine; | ||||
|         *type = LfrfidKeyType::KeyEM4100; | ||||
|         result = true; | ||||
|     } | ||||
| 
 | ||||
|     if(decoder_hid26.read(data, data_size)) { | ||||
|         *type = LfrfidKeyType::KeyHID; | ||||
|         *type = LfrfidKeyType::KeyH10301; | ||||
|         result = true; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ RfidTimerEmulator::RfidTimerEmulator() { | ||||
| } | ||||
| 
 | ||||
| RfidTimerEmulator::~RfidTimerEmulator() { | ||||
|     std::map<Type, EncoderGeneric*>::iterator it; | ||||
|     std::map<LfrfidKeyType, EncoderGeneric*>::iterator it; | ||||
| 
 | ||||
|     for(it = encoders.begin(); it != encoders.end(); ++it) { | ||||
|         delete it->second; | ||||
| @ -14,38 +14,28 @@ RfidTimerEmulator::~RfidTimerEmulator() { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void RfidTimerEmulator::start(Type type) { | ||||
| void RfidTimerEmulator::start(LfrfidKeyType type, const uint8_t* data, uint8_t data_size) { | ||||
|     if(encoders.count(type)) { | ||||
|         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) { | ||||
|         case Type::EM: | ||||
|             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; | ||||
|         if(lfrfid_key_get_type_data_count(type) == data_size) { | ||||
|             current_encoder->init(data, data_size); | ||||
| 
 | ||||
|             api_hal_rfid_tim_emulate(125000); | ||||
|             api_hal_rfid_pins_emulate(); | ||||
| 
 | ||||
|             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++) { | ||||
|                 HAL_NVIC_SetPriority(static_cast<IRQn_Type>(i), 15, 0); | ||||
|             } | ||||
| 
 | ||||
|             HAL_NVIC_SetPriority(TIM1_UP_TIM16_IRQn, 5, 0); | ||||
|             HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); | ||||
| 
 | ||||
|             api_hal_rfid_tim_emulate_start(); | ||||
|         } | ||||
| 
 | ||||
|         api_hal_rfid_tim_emulate(125000); | ||||
|         api_hal_rfid_pins_emulate(); | ||||
| 
 | ||||
|         api_interrupt_add(timer_update_callback, InterruptTypeTimerUpdate, this); | ||||
| 
 | ||||
|         for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { | ||||
|             HAL_NVIC_SetPriority(static_cast<IRQn_Type>(i), 15, 0); | ||||
|         } | ||||
| 
 | ||||
|         HAL_NVIC_SetPriority(TIM1_UP_TIM16_IRQn, 5, 0); | ||||
|         HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); | ||||
| 
 | ||||
|         api_hal_rfid_tim_emulate_start(); | ||||
|     } else { | ||||
|         // not found
 | ||||
|     } | ||||
|  | ||||
| @ -10,24 +10,18 @@ | ||||
| 
 | ||||
| class RfidTimerEmulator { | ||||
| public: | ||||
|     enum class Type : uint8_t { | ||||
|         EM, | ||||
|         HID_H10301, | ||||
|         Indala_40134, | ||||
|     }; | ||||
| 
 | ||||
|     RfidTimerEmulator(); | ||||
|     ~RfidTimerEmulator(); | ||||
|     void start(Type type); | ||||
|     void start(LfrfidKeyType type, const uint8_t* data, uint8_t data_size); | ||||
|     void stop(); | ||||
| 
 | ||||
| private: | ||||
|     EncoderGeneric* current_encoder = nullptr; | ||||
| 
 | ||||
|     std::map<Type, EncoderGeneric*> encoders = { | ||||
|         {Type::EM, new EncoderEM()}, | ||||
|         {Type::HID_H10301, new EncoderHID_H10301()}, | ||||
|         {Type::Indala_40134, new EncoderIndala_40134()}, | ||||
|     std::map<LfrfidKeyType, EncoderGeneric*> encoders = { | ||||
|         {LfrfidKeyType::KeyEM4100, new EncoderEM()}, | ||||
|         {LfrfidKeyType::KeyH10301, new EncoderHID_H10301()}, | ||||
|         {LfrfidKeyType::KeyI40134, new EncoderIndala_40134()}, | ||||
|     }; | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     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) { | ||||
|  | ||||
| @ -9,4 +9,5 @@ public: | ||||
|     void on_exit(LfrfidApp* app) final; | ||||
| 
 | ||||
| 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); | ||||
| 
 | ||||
|     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) { | ||||
|  | ||||
| @ -9,4 +9,5 @@ public: | ||||
|     void on_exit(LfrfidApp* app) final; | ||||
| 
 | ||||
| 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); | ||||
| 
 | ||||
|     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) { | ||||
|  | ||||
| @ -9,4 +9,5 @@ public: | ||||
|     void on_exit(LfrfidApp* app) final; | ||||
| 
 | ||||
| private: | ||||
|     const uint8_t data[3] = {0x1F, 0x2E, 0x3D}; | ||||
| }; | ||||
| @ -35,7 +35,7 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||
|             } | ||||
| 
 | ||||
|             switch(type) { | ||||
|             case LfrfidKeyType::KeyEmarine: | ||||
|             case LfrfidKeyType::KeyEM4100: | ||||
|                 app->set_text_store( | ||||
|                     "[EM] %02X %02X %02X %02X %02X\n" | ||||
|                     "count: %u", | ||||
| @ -46,7 +46,7 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||
|                     data[4], | ||||
|                     success_reads); | ||||
|                 break; | ||||
|             case LfrfidKeyType::KeyHID: | ||||
|             case LfrfidKeyType::KeyH10301: | ||||
|                 app->set_text_store( | ||||
|                     "[HID26] %02X %02X %02X\n" | ||||
|                     "count: %u", | ||||
| @ -55,7 +55,7 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||
|                     data[2], | ||||
|                     success_reads); | ||||
|                 break; | ||||
|             case LfrfidKeyType::KeyIndala: | ||||
|             case LfrfidKeyType::KeyI40134: | ||||
|                 app->set_text_store( | ||||
|                     "[IND] %02X %02X %02X\n" | ||||
|                     "count: %u", | ||||
|  | ||||
| @ -38,7 +38,7 @@ bool LfrfidSceneWrite::on_event(LfrfidApp* app, LfrfidEvent* event) { | ||||
|         LfrfidKeyType type; | ||||
| 
 | ||||
|         app->get_reader()->read(&type, data, LFRFID_KEY_SIZE); | ||||
|         if(type == LfrfidKeyType::KeyEmarine) { | ||||
|         if(type == LfrfidKeyType::KeyEM4100) { | ||||
|             if(memcmp(em_data, data, 5) == 0) { | ||||
|                 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 | ||||
| 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_DIR		= $(LIB_DIR)/onewire | ||||
| CFLAGS			+= -I$(ONEWIRE_DIR) | ||||
| @ -84,7 +75,6 @@ CPP_SOURCES		+= $(wildcard $(ONEWIRE_DIR)/*.cpp) | ||||
| CYFRAL_DIR		= $(LIB_DIR)/cyfral | ||||
| CFLAGS			+= -I$(CYFRAL_DIR) | ||||
| CPP_SOURCES		+= $(wildcard $(CYFRAL_DIR)/*.cpp) | ||||
| endif | ||||
| 
 | ||||
| # common apps api
 | ||||
| CFLAGS			+= -I$(LIB_DIR)/common-api | ||||
| @ -101,3 +91,7 @@ C_SOURCES		+= $(LIB_DIR)/version/version.c | ||||
| CFLAGS			+= -I$(LIB_DIR)/irda | ||||
| 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