Picopass write (#1658)
* [picopass] Prevent false success with non-standard key * UI for writing * worker function for write * Update write command value * Show card read failure message Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									e4c6158d65
								
							
						
					
					
						commit
						8e9043003f
					
				| @ -190,12 +190,87 @@ ReturnCode picopass_read_card(PicopassBlock* AA1) { | |||||||
|     return ERR_NONE; |     return ERR_NONE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | ReturnCode picopass_write_card(PicopassBlock* AA1) { | ||||||
|  |     rfalPicoPassIdentifyRes idRes; | ||||||
|  |     rfalPicoPassSelectRes selRes; | ||||||
|  |     rfalPicoPassReadCheckRes rcRes; | ||||||
|  |     rfalPicoPassCheckRes chkRes; | ||||||
|  | 
 | ||||||
|  |     ReturnCode err; | ||||||
|  | 
 | ||||||
|  |     uint8_t div_key[8] = {0}; | ||||||
|  |     uint8_t mac[4] = {0}; | ||||||
|  |     uint8_t ccnr[12] = {0}; | ||||||
|  | 
 | ||||||
|  |     err = rfalPicoPassPollerIdentify(&idRes); | ||||||
|  |     if(err != ERR_NONE) { | ||||||
|  |         FURI_LOG_E(TAG, "rfalPicoPassPollerIdentify error %d", err); | ||||||
|  |         return err; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     err = rfalPicoPassPollerSelect(idRes.CSN, &selRes); | ||||||
|  |     if(err != ERR_NONE) { | ||||||
|  |         FURI_LOG_E(TAG, "rfalPicoPassPollerSelect error %d", err); | ||||||
|  |         return err; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     err = rfalPicoPassPollerReadCheck(&rcRes); | ||||||
|  |     if(err != ERR_NONE) { | ||||||
|  |         FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err); | ||||||
|  |         return err; | ||||||
|  |     } | ||||||
|  |     memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0
 | ||||||
|  | 
 | ||||||
|  |     loclass_diversifyKey(selRes.CSN, picopass_iclass_key, div_key); | ||||||
|  |     loclass_opt_doReaderMAC(ccnr, div_key, mac); | ||||||
|  | 
 | ||||||
|  |     err = rfalPicoPassPollerCheck(mac, &chkRes); | ||||||
|  |     if(err != ERR_NONE) { | ||||||
|  |         FURI_LOG_E(TAG, "rfalPicoPassPollerCheck error %d", err); | ||||||
|  |         return err; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for(size_t i = 6; i < 10; i++) { | ||||||
|  |         FURI_LOG_D(TAG, "rfalPicoPassPollerWriteBlock %d", i); | ||||||
|  |         uint8_t data[9] = {0}; | ||||||
|  |         data[0] = i; | ||||||
|  |         memcpy(data + 1, AA1[i].data, RFAL_PICOPASS_MAX_BLOCK_LEN); | ||||||
|  |         loclass_doMAC_N(data, sizeof(data), div_key, mac); | ||||||
|  |         FURI_LOG_D( | ||||||
|  |             TAG, | ||||||
|  |             "loclass_doMAC_N %d %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x", | ||||||
|  |             i, | ||||||
|  |             data[1], | ||||||
|  |             data[2], | ||||||
|  |             data[3], | ||||||
|  |             data[4], | ||||||
|  |             data[5], | ||||||
|  |             data[6], | ||||||
|  |             data[7], | ||||||
|  |             data[8], | ||||||
|  |             mac[0], | ||||||
|  |             mac[1], | ||||||
|  |             mac[2], | ||||||
|  |             mac[3]); | ||||||
|  | 
 | ||||||
|  |         err = rfalPicoPassPollerWriteBlock(i, AA1[i].data, mac); | ||||||
|  |         if(err != ERR_NONE) { | ||||||
|  |             FURI_LOG_E(TAG, "rfalPicoPassPollerWriteBlock error %d", err); | ||||||
|  |             return err; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ERR_NONE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int32_t picopass_worker_task(void* context) { | int32_t picopass_worker_task(void* context) { | ||||||
|     PicopassWorker* picopass_worker = context; |     PicopassWorker* picopass_worker = context; | ||||||
| 
 | 
 | ||||||
|     picopass_worker_enable_field(); |     picopass_worker_enable_field(); | ||||||
|     if(picopass_worker->state == PicopassWorkerStateDetect) { |     if(picopass_worker->state == PicopassWorkerStateDetect) { | ||||||
|         picopass_worker_detect(picopass_worker); |         picopass_worker_detect(picopass_worker); | ||||||
|  |     } else if(picopass_worker->state == PicopassWorkerStateWrite) { | ||||||
|  |         picopass_worker_write(picopass_worker); | ||||||
|     } |     } | ||||||
|     picopass_worker_disable_field(ERR_NONE); |     picopass_worker_disable_field(ERR_NONE); | ||||||
| 
 | 
 | ||||||
| @ -212,27 +287,60 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) { | |||||||
|     PicopassPacs* pacs = &dev_data->pacs; |     PicopassPacs* pacs = &dev_data->pacs; | ||||||
|     ReturnCode err; |     ReturnCode err; | ||||||
| 
 | 
 | ||||||
|  |     PicopassWorkerEvent nextState = PicopassWorkerEventSuccess; | ||||||
|  | 
 | ||||||
|     while(picopass_worker->state == PicopassWorkerStateDetect) { |     while(picopass_worker->state == PicopassWorkerStateDetect) { | ||||||
|         if(picopass_detect_card(1000) == ERR_NONE) { |         if(picopass_detect_card(1000) == ERR_NONE) { | ||||||
|             // Process first found device
 |             // Process first found device
 | ||||||
|             err = picopass_read_card(AA1); |             err = picopass_read_card(AA1); | ||||||
|             if(err != ERR_NONE) { |             if(err != ERR_NONE) { | ||||||
|                 FURI_LOG_E(TAG, "picopass_read_card error %d", err); |                 FURI_LOG_E(TAG, "picopass_read_card error %d", err); | ||||||
|  |                 nextState = PicopassWorkerEventFail; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             if(nextState == PicopassWorkerEventSuccess) { | ||||||
|                 err = picopass_device_parse_credential(AA1, pacs); |                 err = picopass_device_parse_credential(AA1, pacs); | ||||||
|  |             } | ||||||
|             if(err != ERR_NONE) { |             if(err != ERR_NONE) { | ||||||
|                 FURI_LOG_E(TAG, "picopass_device_parse_credential error %d", err); |                 FURI_LOG_E(TAG, "picopass_device_parse_credential error %d", err); | ||||||
|  |                 nextState = PicopassWorkerEventFail; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             if(nextState == PicopassWorkerEventSuccess) { | ||||||
|                 err = picopass_device_parse_wiegand(pacs->credential, &pacs->record); |                 err = picopass_device_parse_wiegand(pacs->credential, &pacs->record); | ||||||
|  |             } | ||||||
|             if(err != ERR_NONE) { |             if(err != ERR_NONE) { | ||||||
|                 FURI_LOG_E(TAG, "picopass_device_parse_wiegand error %d", err); |                 FURI_LOG_E(TAG, "picopass_device_parse_wiegand error %d", err); | ||||||
|  |                 nextState = PicopassWorkerEventFail; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Notify caller and exit
 |             // Notify caller and exit
 | ||||||
|             if(picopass_worker->callback) { |             if(picopass_worker->callback) { | ||||||
|                 picopass_worker->callback(PicopassWorkerEventSuccess, picopass_worker->context); |                 picopass_worker->callback(nextState, picopass_worker->context); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         furi_delay_ms(100); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void picopass_worker_write(PicopassWorker* picopass_worker) { | ||||||
|  |     PicopassDeviceData* dev_data = picopass_worker->dev_data; | ||||||
|  |     PicopassBlock* AA1 = dev_data->AA1; | ||||||
|  |     ReturnCode err; | ||||||
|  |     PicopassWorkerEvent nextState = PicopassWorkerEventSuccess; | ||||||
|  | 
 | ||||||
|  |     while(picopass_worker->state == PicopassWorkerStateWrite) { | ||||||
|  |         if(picopass_detect_card(1000) == ERR_NONE) { | ||||||
|  |             err = picopass_write_card(AA1); | ||||||
|  |             if(err != ERR_NONE) { | ||||||
|  |                 FURI_LOG_E(TAG, "picopass_write_card error %d", err); | ||||||
|  |                 nextState = PicopassWorkerEventFail; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Notify caller and exit
 | ||||||
|  |             if(picopass_worker->callback) { | ||||||
|  |                 picopass_worker->callback(nextState, picopass_worker->context); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ typedef enum { | |||||||
|     PicopassWorkerStateReady, |     PicopassWorkerStateReady, | ||||||
|     // Main worker states
 |     // Main worker states
 | ||||||
|     PicopassWorkerStateDetect, |     PicopassWorkerStateDetect, | ||||||
|  |     PicopassWorkerStateWrite, | ||||||
|     // Transition
 |     // Transition
 | ||||||
|     PicopassWorkerStateStop, |     PicopassWorkerStateStop, | ||||||
| } PicopassWorkerState; | } PicopassWorkerState; | ||||||
|  | |||||||
| @ -31,3 +31,4 @@ void picopass_worker_change_state(PicopassWorker* picopass_worker, PicopassWorke | |||||||
| int32_t picopass_worker_task(void* context); | int32_t picopass_worker_task(void* context); | ||||||
| 
 | 
 | ||||||
| void picopass_worker_detect(PicopassWorker* picopass_worker); | void picopass_worker_detect(PicopassWorker* picopass_worker); | ||||||
|  | void picopass_worker_write(PicopassWorker* picopass_worker); | ||||||
|  | |||||||
| @ -9,3 +9,5 @@ ADD_SCENE(picopass, file_select, FileSelect) | |||||||
| ADD_SCENE(picopass, device_info, DeviceInfo) | ADD_SCENE(picopass, device_info, DeviceInfo) | ||||||
| ADD_SCENE(picopass, delete, Delete) | ADD_SCENE(picopass, delete, Delete) | ||||||
| ADD_SCENE(picopass, delete_success, DeleteSuccess) | ADD_SCENE(picopass, delete_success, DeleteSuccess) | ||||||
|  | ADD_SCENE(picopass, write_card, WriteCard) | ||||||
|  | ADD_SCENE(picopass, write_card_success, WriteCardSuccess) | ||||||
|  | |||||||
| @ -37,8 +37,6 @@ bool picopass_scene_read_card_on_event(void* context, SceneManagerEvent event) { | |||||||
|             scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess); |             scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|         } |         } | ||||||
|     } else if(event.type == SceneManagerEventTypeTick) { |  | ||||||
|         consumed = true; |  | ||||||
|     } |     } | ||||||
|     return consumed; |     return consumed; | ||||||
| } | } | ||||||
|  | |||||||
| @ -29,6 +29,19 @@ void picopass_scene_read_card_success_on_enter(void* context) { | |||||||
|     PicopassPacs* pacs = &picopass->dev->dev_data.pacs; |     PicopassPacs* pacs = &picopass->dev->dev_data.pacs; | ||||||
|     Widget* widget = picopass->widget; |     Widget* widget = picopass->widget; | ||||||
| 
 | 
 | ||||||
|  |     if(pacs->record.bitLength == 0) { | ||||||
|  |         string_cat_printf(wiegand_str, "Read Failed"); | ||||||
|  | 
 | ||||||
|  |         widget_add_button_element( | ||||||
|  |             widget, | ||||||
|  |             GuiButtonTypeLeft, | ||||||
|  |             "Retry", | ||||||
|  |             picopass_scene_read_card_success_widget_callback, | ||||||
|  |             picopass); | ||||||
|  | 
 | ||||||
|  |         widget_add_string_element( | ||||||
|  |             widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); | ||||||
|  |     } else { | ||||||
|         size_t bytesLength = 1 + pacs->record.bitLength / 8; |         size_t bytesLength = 1 + pacs->record.bitLength / 8; | ||||||
|         string_set_str(credential_str, ""); |         string_set_str(credential_str, ""); | ||||||
|         for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { |         for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { | ||||||
| @ -59,8 +72,14 @@ void picopass_scene_read_card_success_on_enter(void* context) { | |||||||
|         widget_add_string_element( |         widget_add_string_element( | ||||||
|             widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); |             widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); | ||||||
|         widget_add_string_element( |         widget_add_string_element( | ||||||
|         widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str)); |             widget, | ||||||
| 
 |             64, | ||||||
|  |             32, | ||||||
|  |             AlignCenter, | ||||||
|  |             AlignCenter, | ||||||
|  |             FontSecondary, | ||||||
|  |             string_get_cstr(credential_str)); | ||||||
|  |     } | ||||||
|     string_clear(credential_str); |     string_clear(credential_str); | ||||||
|     string_clear(wiegand_str); |     string_clear(wiegand_str); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -24,6 +24,8 @@ void picopass_scene_saved_menu_on_enter(void* context) { | |||||||
|         picopass); |         picopass); | ||||||
|     submenu_add_item( |     submenu_add_item( | ||||||
|         submenu, "Info", SubmenuIndexInfo, picopass_scene_saved_menu_submenu_callback, picopass); |         submenu, "Info", SubmenuIndexInfo, picopass_scene_saved_menu_submenu_callback, picopass); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Write", SubmenuIndexWrite, picopass_scene_saved_menu_submenu_callback, picopass); | ||||||
| 
 | 
 | ||||||
|     submenu_set_selected_item( |     submenu_set_selected_item( | ||||||
|         picopass->submenu, |         picopass->submenu, | ||||||
| @ -46,6 +48,9 @@ bool picopass_scene_saved_menu_on_event(void* context, SceneManagerEvent event) | |||||||
|         } else if(event.event == SubmenuIndexInfo) { |         } else if(event.event == SubmenuIndexInfo) { | ||||||
|             scene_manager_next_scene(picopass->scene_manager, PicopassSceneDeviceInfo); |             scene_manager_next_scene(picopass->scene_manager, PicopassSceneDeviceInfo); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|  |         } else if(event.event == SubmenuIndexWrite) { | ||||||
|  |             scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCard); | ||||||
|  |             consumed = true; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										53
									
								
								applications/picopass/scenes/picopass_scene_write_card.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								applications/picopass/scenes/picopass_scene_write_card.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | #include "../picopass_i.h" | ||||||
|  | #include <dolphin/dolphin.h> | ||||||
|  | 
 | ||||||
|  | void picopass_write_card_worker_callback(PicopassWorkerEvent event, void* context) { | ||||||
|  |     UNUSED(event); | ||||||
|  |     Picopass* picopass = context; | ||||||
|  |     view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventWorkerExit); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void picopass_scene_write_card_on_enter(void* context) { | ||||||
|  |     Picopass* picopass = context; | ||||||
|  |     DOLPHIN_DEED(DolphinDeedNfcSave); | ||||||
|  | 
 | ||||||
|  |     // Setup view
 | ||||||
|  |     Popup* popup = picopass->popup; | ||||||
|  |     popup_set_header(popup, "Writing\npicopass\ncard", 68, 30, AlignLeft, AlignTop); | ||||||
|  |     popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); | ||||||
|  | 
 | ||||||
|  |     // Start worker
 | ||||||
|  |     view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup); | ||||||
|  |     picopass_worker_start( | ||||||
|  |         picopass->worker, | ||||||
|  |         PicopassWorkerStateWrite, | ||||||
|  |         &picopass->dev->dev_data, | ||||||
|  |         picopass_write_card_worker_callback, | ||||||
|  |         picopass); | ||||||
|  | 
 | ||||||
|  |     picopass_blink_start(picopass); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool picopass_scene_write_card_on_event(void* context, SceneManagerEvent event) { | ||||||
|  |     Picopass* picopass = context; | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|  |         if(event.event == PicopassCustomEventWorkerExit) { | ||||||
|  |             scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCardSuccess); | ||||||
|  |             consumed = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void picopass_scene_write_card_on_exit(void* context) { | ||||||
|  |     Picopass* picopass = context; | ||||||
|  | 
 | ||||||
|  |     // Stop worker
 | ||||||
|  |     picopass_worker_stop(picopass->worker); | ||||||
|  |     // Clear view
 | ||||||
|  |     popup_reset(picopass->popup); | ||||||
|  | 
 | ||||||
|  |     picopass_blink_stop(picopass); | ||||||
|  | } | ||||||
| @ -0,0 +1,57 @@ | |||||||
|  | #include "../picopass_i.h" | ||||||
|  | #include <dolphin/dolphin.h> | ||||||
|  | 
 | ||||||
|  | void picopass_scene_write_card_success_widget_callback( | ||||||
|  |     GuiButtonType result, | ||||||
|  |     InputType type, | ||||||
|  |     void* context) { | ||||||
|  |     furi_assert(context); | ||||||
|  |     Picopass* picopass = context; | ||||||
|  | 
 | ||||||
|  |     if(type == InputTypeShort) { | ||||||
|  |         view_dispatcher_send_custom_event(picopass->view_dispatcher, result); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void picopass_scene_write_card_success_on_enter(void* context) { | ||||||
|  |     Picopass* picopass = context; | ||||||
|  |     Widget* widget = picopass->widget; | ||||||
|  | 
 | ||||||
|  |     DOLPHIN_DEED(DolphinDeedNfcReadSuccess); | ||||||
|  | 
 | ||||||
|  |     // Send notification
 | ||||||
|  |     notification_message(picopass->notifications, &sequence_success); | ||||||
|  | 
 | ||||||
|  |     widget_add_button_element( | ||||||
|  |         widget, | ||||||
|  |         GuiButtonTypeLeft, | ||||||
|  |         "Retry", | ||||||
|  |         picopass_scene_write_card_success_widget_callback, | ||||||
|  |         picopass); | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool picopass_scene_write_card_success_on_event(void* context, SceneManagerEvent event) { | ||||||
|  |     Picopass* picopass = context; | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|  |         if(event.event == GuiButtonTypeLeft) { | ||||||
|  |             consumed = scene_manager_previous_scene(picopass->scene_manager); | ||||||
|  |         } else if(event.event == GuiButtonTypeRight) { | ||||||
|  |             // Clear device name
 | ||||||
|  |             picopass_device_set_name(picopass->dev, ""); | ||||||
|  |             scene_manager_next_scene(picopass->scene_manager, PicopassSceneCardMenu); | ||||||
|  |             consumed = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void picopass_scene_write_card_success_on_exit(void* context) { | ||||||
|  |     Picopass* picopass = context; | ||||||
|  | 
 | ||||||
|  |     // Clear view
 | ||||||
|  |     widget_reset(picopass->widget); | ||||||
|  | } | ||||||
| @ -26,7 +26,7 @@ enum { | |||||||
|     RFAL_PICOPASS_CMD_READCHECK = 0x88, |     RFAL_PICOPASS_CMD_READCHECK = 0x88, | ||||||
|     RFAL_PICOPASS_CMD_CHECK = 0x05, |     RFAL_PICOPASS_CMD_CHECK = 0x05, | ||||||
|     RFAL_PICOPASS_CMD_READ = 0x0C, |     RFAL_PICOPASS_CMD_READ = 0x0C, | ||||||
|     RFAL_PICOPASS_CMD_WRITE = 0x0C, |     RFAL_PICOPASS_CMD_WRITE = 0x87, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ | |||||||
| #include "rfal_picopass.h" | #include "rfal_picopass.h" | ||||||
| #include "utils.h" | #include "utils.h" | ||||||
| 
 | 
 | ||||||
|  | #define TAG "RFAL_PICOPASS" | ||||||
|  | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t CMD; |     uint8_t CMD; | ||||||
|     uint8_t CSN[RFAL_PICOPASS_UID_LEN]; |     uint8_t CSN[RFAL_PICOPASS_UID_LEN]; | ||||||
| @ -169,18 +171,14 @@ ReturnCode rfalPicoPassPollerWriteBlock(uint8_t blockNum, uint8_t data[8], uint8 | |||||||
|     uint16_t recvLen = 0; |     uint16_t recvLen = 0; | ||||||
|     uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; |     uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; | ||||||
|     uint32_t fwt = rfalConvMsTo1fc(20); |     uint32_t fwt = rfalConvMsTo1fc(20); | ||||||
|     rfalPicoPassReadBlockRes readRes; |     rfalPicoPassReadBlockRes block; | ||||||
| 
 | 
 | ||||||
|     ret = rfalTransceiveBlockingTxRx( |     ret = rfalTransceiveBlockingTxRx( | ||||||
|         txBuf, |         txBuf, sizeof(txBuf), (uint8_t*)&block, sizeof(block), &recvLen, flags, fwt); | ||||||
|         sizeof(txBuf), |  | ||||||
|         (uint8_t*)&readRes, |  | ||||||
|         sizeof(rfalPicoPassReadBlockRes), |  | ||||||
|         &recvLen, |  | ||||||
|         flags, |  | ||||||
|         fwt); |  | ||||||
| 
 | 
 | ||||||
|  |     if(ret == ERR_NONE) { | ||||||
|         // TODO: compare response
 |         // TODO: compare response
 | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Eric Betts
						Eric Betts