diff --git a/source_code/.vs/Mooltipass/v14/.atsuo b/source_code/.vs/Mooltipass/v14/.atsuo index b47b6c5d1..bf0deb62b 100644 Binary files a/source_code/.vs/Mooltipass/v14/.atsuo and b/source_code/.vs/Mooltipass/v14/.atsuo differ diff --git a/source_code/src/GUI/gui_basic_functions.c b/source_code/src/GUI/gui_basic_functions.c index 5f6b9d6ed..d5ab19351 100644 --- a/source_code/src/GUI/gui_basic_functions.c +++ b/source_code/src/GUI/gui_basic_functions.c @@ -139,19 +139,11 @@ int8_t getTouchedPositionAnswer(uint8_t led_mask) return -1; } // Read usb comms as the plugin could ask to cancel the request - if ((getMooltipassParameterInEeprom(USER_REQ_CANCEL_PARAM) != FALSE) && (usbRawHidRecv(incomingData) == RETURN_COM_TRANSF_OK)) + if (usbCancelRequestReceived() == RETURN_OK) { - if (incomingData[HID_TYPE_FIELD] == CMD_CANCEL_REQUEST) - { - // Request cancelled - return -1; - } - else - { - // Another packet (that shouldn't be sent!), ask to retry later... - usbSendMessage(CMD_PLEASE_RETRY, 0, incomingData); - } + return -1; } + touch_detect_result = touchDetectionRoutine(led_mask) & TOUCH_PRESS_MASK & additional_mask; } while (!touch_detect_result); diff --git a/source_code/src/GUI/gui_credentials_functions.c b/source_code/src/GUI/gui_credentials_functions.c index 7f8032b99..b3afff9d9 100644 --- a/source_code/src/GUI/gui_credentials_functions.c +++ b/source_code/src/GUI/gui_credentials_functions.c @@ -367,11 +367,23 @@ uint16_t guiAskForLoginSelect(pNode* p, cNode* c, uint16_t parentNodeAddress, ui cur_children_nb++; } } + else if (wheel_action == WHEEL_ACTION_LONG_CLICK) + { + // Long click to go back (checked by function caller) + return NODE_ADDR_NULL; + } + // Timeout or card removed if ((hasTimerExpired(TIMER_USERINT, TRUE) == TIMER_EXPIRED) || (isSmartCardAbsent() == RETURN_OK)) { return NODE_ADDR_NULL; } + + // Request cancelled by plugin + if (usbCancelRequestReceived() == RETURN_OK) + { + return NODE_ADDR_NULL; + } } #endif } @@ -832,6 +844,9 @@ uint16_t loginSelectionScreen(void) // Arm timer for scrolling (caps timer that isn't relevant here) activateTimer(TIMER_CAPS, SCROLLING_DEL); + // Clear possible detections + miniWheelClearDetections(); + while(1) { // If needed, re-compute the string offsets & extra chars diff --git a/source_code/src/GUI/gui_pin_functions.c b/source_code/src/GUI/gui_pin_functions.c index eac6a6e4c..2c4ac8aee 100644 --- a/source_code/src/GUI/gui_pin_functions.c +++ b/source_code/src/GUI/gui_pin_functions.c @@ -279,13 +279,8 @@ RET_TYPE guiGetPinFromUser(volatile uint16_t* pin_code, uint8_t stringID) } // Change digit position or return/proceed - if ((detection_result == WHEEL_ACTION_LONG_CLICK) || (detection_result == WHEEL_ACTION_CLICK_UP)) + if (detection_result == WHEEL_ACTION_LONG_CLICK) { - if (selected_digit == 1) - { - //oledFillXY(0, 23, 18, 18, 0x00); - //oledBitmapDrawFlash(0, 24, BITMAP_CROSS, 0); - } if (selected_digit > 0) { // When going back set pin digit to 0 @@ -299,12 +294,8 @@ RET_TYPE guiGetPinFromUser(volatile uint16_t* pin_code, uint8_t stringID) } guiDisplayPinOnPinEnteringScreen(current_pin, selected_digit, stringID); } - else if ((detection_result == WHEEL_ACTION_SHORT_CLICK) || (detection_result == WHEEL_ACTION_CLICK_DOWN)) + else if (detection_result == WHEEL_ACTION_SHORT_CLICK) { - if (selected_digit == 2) - { - //oledBitmapDrawFlash(0, SSD1305_OLED_WIDTH-15, BITMAP_TICK, 0); - } if (selected_digit < 3) { selected_digit++; @@ -318,10 +309,6 @@ RET_TYPE guiGetPinFromUser(volatile uint16_t* pin_code, uint8_t stringID) } } - // Reset default font - //oledSetFont(FONT_DEFAULT); - //oledWriteInactiveBuffer(); - // Store the pin *pin_code = (uint16_t)(((uint16_t)(current_pin[0]) << 12) | (((uint16_t)current_pin[1]) << 8) | (current_pin[2] << 4) | current_pin[3]); @@ -329,9 +316,6 @@ RET_TYPE guiGetPinFromUser(volatile uint16_t* pin_code, uint8_t stringID) memset((void*)current_pin, 0, 4); oledSetFont(FONT_DEFAULT); - // Prevent touches until the user lifts his finger - //touchInhibitUntilRelease(); - // Return success status return ret_val; #endif diff --git a/source_code/src/GUI/gui_screen_functions.c b/source_code/src/GUI/gui_screen_functions.c index dd42339ae..aeec5ebba 100644 --- a/source_code/src/GUI/gui_screen_functions.c +++ b/source_code/src/GUI/gui_screen_functions.c @@ -886,7 +886,6 @@ RET_TYPE guiAskForConfirmation(uint8_t nb_args, confirmationText_t* text_object) } #elif defined(MINI_VERSION) RET_TYPE input_answer = MINI_INPUT_RET_NONE; - uint8_t incomingData[RAWHID_TX_SIZE]; RET_TYPE detect_result; // Switch on lights @@ -908,18 +907,9 @@ RET_TYPE guiAskForConfirmation(uint8_t nb_args, confirmationText_t* text_object) } // Read usb comms as the plugin could ask to cancel the request - if ((getMooltipassParameterInEeprom(USER_REQ_CANCEL_PARAM) != FALSE) && (usbRawHidRecv(incomingData) == RETURN_COM_TRANSF_OK)) + if (usbCancelRequestReceived() == RETURN_OK) { - if (incomingData[HID_TYPE_FIELD] == CMD_CANCEL_REQUEST) - { - // Request canceled - input_answer = MINI_INPUT_RET_TIMEOUT; - } - else - { - // Another packet (that shouldn't be sent!), ask to retry later... - usbSendMessage(CMD_PLEASE_RETRY, 0, incomingData); - } + input_answer = MINI_INPUT_RET_TIMEOUT; } // Check if something has been pressed @@ -979,6 +969,10 @@ RET_TYPE guiAskForConfirmation(uint8_t nb_args, confirmationText_t* text_object) { return RETURN_OK; } + else if (input_answer == MINI_INPUT_RET_BACK) + { + return RETURN_BACK; + } else { return RETURN_NOK; diff --git a/source_code/src/LOGIC/logic_aes_and_comms.c b/source_code/src/LOGIC/logic_aes_and_comms.c index 2e935b2d0..9c7d05e8d 100644 --- a/source_code/src/LOGIC/logic_aes_and_comms.c +++ b/source_code/src/LOGIC/logic_aes_and_comms.c @@ -32,6 +32,7 @@ #include "timer_manager.h" #include "logic_eeprom.h" #include "hid_defines.h" +#include "mini_inputs.h" #include "aes256_ctr.h" #include "node_mgmt.h" #include "flash_mem.h" @@ -945,8 +946,9 @@ RET_TYPE checkPasswordForContext(uint8_t* password) * \brief Ask the user to enter the login password of a given child * \param child_address Address of the child * \param service_name Service name +* \param RETURN_OK or RETURN_BACK */ -void askUserForLoginAndPasswordKeybOutput(uint16_t child_address, char* service_name) +RET_TYPE askUserForLoginAndPasswordKeybOutput(uint16_t child_address, char* service_name) { confirmationText_t temp_conf_text; @@ -957,6 +959,103 @@ void askUserForLoginAndPasswordKeybOutput(uint16_t child_address, char* service_ readChildNode(&temp_cnode, child_address); temp_conf_text.lines[0] = service_name; + #ifdef MINI_VERSION + while(TRUE) + { + // If login isn't empty, ask the user if he wants to output the login + if (temp_cnode.login[0] != 0) + { + // Check if we're connected through USB + if (isUsbConfigured()) + { + temp_conf_text.lines[1] = readStoredStringToBuffer(ID_STRING_ENTERLOGINQ); + RET_TYPE confirmation_result = guiAskForConfirmation(2, &temp_conf_text); + if (confirmation_result == RETURN_OK) + { + usbKeybPutStr((char*)temp_cnode.login); + if (getMooltipassParameterInEeprom(KEY_AFTER_LOGIN_SEND_BOOL_PARAM) != FALSE) + { + usbKeyboardPress(getMooltipassParameterInEeprom(KEY_AFTER_LOGIN_SEND_PARAM), 0); + } + } + else if (confirmation_result == RETURN_BACK) + { + return RETURN_BACK; + } + } + else + { + temp_conf_text.lines[1] = readStoredStringToBuffer(ID_STRING_SHOW_LOGINQ); + RET_TYPE confirmation_result = guiAskForConfirmation(2, &temp_conf_text); + if (confirmation_result == RETURN_OK) + { + guiDisplayLoginOrPasswordOnScreen((char*)temp_cnode.login); + } + else if (confirmation_result == RETURN_BACK) + { + return RETURN_BACK; + } + } + } + + decrypt32bBlockOfDataAndClearCTVFlag(temp_cnode.password, temp_cnode.ctr); + // Ask the user if he wants to output the password + if (isUsbConfigured()) + { + temp_conf_text.lines[1] = readStoredStringToBuffer(ID_STRING_ENTERPASSQ); + RET_TYPE confirmation_result = guiAskForConfirmation(2, &temp_conf_text); + if (confirmation_result == RETURN_OK) + { + usbKeybPutStr((char*)temp_cnode.password); + if (getMooltipassParameterInEeprom(KEY_AFTER_PASS_SEND_BOOL_PARAM) != FALSE) + { + usbKeyboardPress(getMooltipassParameterInEeprom(KEY_AFTER_PASS_SEND_PARAM), 0); + } + return RETURN_OK; + } + else if (confirmation_result == RETURN_BACK) + { + if (temp_cnode.login[0] != 0) + { + continue; + } + else + { + return RETURN_BACK; + } + } + else + { + return RETURN_NOK; + } + } + else + { + temp_conf_text.lines[1] = readStoredStringToBuffer(ID_STRING_SHOW_PASSQ); + RET_TYPE confirmation_result = guiAskForConfirmation(2, &temp_conf_text); + if (confirmation_result == RETURN_OK) + { + guiDisplayLoginOrPasswordOnScreen((char*)temp_cnode.password); + return RETURN_OK; + } + else if (confirmation_result == RETURN_BACK) + { + if (temp_cnode.login[0] != 0) + { + continue; + } + else + { + return RETURN_BACK; + } + } + else + { + return RETURN_NOK; + } + } + } + #else // If login isn't empty, ask the user if he wants to output the login if (temp_cnode.login[0] != 0) { @@ -972,7 +1071,7 @@ void askUserForLoginAndPasswordKeybOutput(uint16_t child_address, char* service_ usbKeyboardPress(getMooltipassParameterInEeprom(KEY_AFTER_LOGIN_SEND_PARAM), 0); } } - } + } else { temp_conf_text.lines[1] = readStoredStringToBuffer(ID_STRING_SHOW_LOGINQ); @@ -1005,7 +1104,10 @@ void askUserForLoginAndPasswordKeybOutput(uint16_t child_address, char* service_ guiDisplayLoginOrPasswordOnScreen((char*)temp_cnode.password); } } - } + #endif + } + + return RETURN_OK; } /*! \fn favoritePickingLogic(void) @@ -1022,5 +1124,42 @@ void favoritePickingLogic(void) */ void loginSelectLogic(void) { - askUserForLoginAndPasswordKeybOutput(guiAskForLoginSelect(&temp_pnode, &temp_cnode, loginSelectionScreen(), TRUE), (char*)temp_pnode.service); + #ifdef MINI_VERSION + // Special ifdef to allow going back action in the mooltipass mini + uint16_t chosen_service_addr; + uint16_t chosen_login_addr; + //askUserForLoginAndPasswordKeybOutput(guiAskForLoginSelect(&temp_pnode, &temp_cnode, loginSelectionScreen(), TRUE), (char*)temp_pnode.service);return; + while (TRUE) + { + // Ask user to select a service + chosen_service_addr = loginSelectionScreen(); + + // No service was chosen + if (chosen_service_addr == NODE_ADDR_NULL) + { + return; + } + + // If there are different logins for this service, ask the user to pick one + chosen_login_addr = guiAskForLoginSelect(&temp_pnode, &temp_cnode, chosen_service_addr, TRUE); + + // In case the user went back + if ((chosen_login_addr == NODE_ADDR_NULL) && (miniGetLastReturnedAction() == WHEEL_ACTION_LONG_CLICK)) + { + continue; + } + + // Ask the user permission to enter login / password, check for back action + if (askUserForLoginAndPasswordKeybOutput(chosen_login_addr, (char*)temp_pnode.service) == RETURN_BACK) + { + continue; + } + else + { + return; + } + } + #else + askUserForLoginAndPasswordKeybOutput(guiAskForLoginSelect(&temp_pnode, &temp_cnode, loginSelectionScreen(), TRUE), (char*)temp_pnode.service); + #endif } \ No newline at end of file diff --git a/source_code/src/USB/usb_cmd_parser.c b/source_code/src/USB/usb_cmd_parser.c index 0168ca501..0a47a9b38 100644 --- a/source_code/src/USB/usb_cmd_parser.c +++ b/source_code/src/USB/usb_cmd_parser.c @@ -147,6 +147,33 @@ RET_TYPE checkTextField(uint8_t* data, uint8_t len, uint8_t max_len) } } +/*! \fn usbCancelRequestReceived(void) +* \brief Check if a cancel request packet was received +* \return RETURN_OK if packet received, RETURN_NOK otherwise +*/ +RET_TYPE usbCancelRequestReceived(void) +{ + // Our USB data buffer + uint8_t incomingData[RAWHID_TX_SIZE]; + + // Read usb comms as the plugin could ask to cancel the request + if ((getMooltipassParameterInEeprom(USER_REQ_CANCEL_PARAM) != FALSE) && (usbRawHidRecv(incomingData) == RETURN_COM_TRANSF_OK)) + { + if (incomingData[HID_TYPE_FIELD] == CMD_CANCEL_REQUEST) + { + // Request canceled + return RETURN_OK; + } + else + { + // Another packet (that shouldn't be sent!), ask to retry later... + usbSendMessage(CMD_PLEASE_RETRY, 0, incomingData); + } + } + + return RETURN_NOK; +} + /*! \fn usbProcessIncoming(uint8_t caller_id) * \brief Process a possible incoming USB packet * \param caller_id UID of the calling function diff --git a/source_code/src/USB/usb_cmd_parser.h b/source_code/src/USB/usb_cmd_parser.h index 4e0aa3fb6..0f3a77f2e 100644 --- a/source_code/src/USB/usb_cmd_parser.h +++ b/source_code/src/USB/usb_cmd_parser.h @@ -134,6 +134,7 @@ typedef struct /*** PROTOTYPES ***/ RET_TYPE checkTextField(uint8_t* data, uint8_t len, uint8_t max_len); void usbProcessIncoming(uint8_t caller_id); +RET_TYPE usbCancelRequestReceived(void); void leaveMemoryManagementMode(void); #endif diff --git a/source_code/src/defines.h b/source_code/src/defines.h index 647b88554..d4e018345 100644 --- a/source_code/src/defines.h +++ b/source_code/src/defines.h @@ -240,7 +240,7 @@ enum button_return_t {LEFT_BUTTON = 0, RIGHT_BUTTON = 1, GUARD_BUTTON enum service_compare_mode_t {COMPARE_MODE_MATCH = 0, COMPARE_MODE_COMPARE = 1}; enum service_type_t {SERVICE_CRED_TYPE = 0, SERVICE_DATA_TYPE = 1}; enum timer_flag_t {TIMER_EXPIRED = 0, TIMER_RUNNING = 1}; -enum return_type_t {RETURN_NOK = -1, RETURN_OK = 0}; +enum return_type_t {RETURN_NOK = -1, RETURN_OK = 0, RETURN_BACK = 2}; enum flash_ret_t {RETURN_INVALID_PARAM = -2, RETURN_WRITE_ERR = -3, RETURN_READ_ERR = -4, RETURN_NO_MATCH = -5}; enum justify_t {OLED_LEFT = 0, OLED_RIGHT = 1, OLED_CENTRE = 2}; enum scrolling_flag_t {OLED_SCROLL_NONE = 0, OLED_SCROLL_UP = 1, OLED_SCROLL_DOWN = 2, OLED_SCROLL_FLIP = 3}; diff --git a/source_code/src/mini_inputs.c b/source_code/src/mini_inputs.c index 04f304e08..af9c1132f 100644 --- a/source_code/src/mini_inputs.c +++ b/source_code/src/mini_inputs.c @@ -51,6 +51,8 @@ volatile uint8_t last_wheel_sm; uint8_t discard_release_event = FALSE; // Wheel direction reverse bool uint8_t wheel_reverse_bool = FALSE; +// Last detection type returned (cleared when calling cleardetections) +RET_TYPE last_detection_type_ret = WHEEL_ACTION_NONE; /*! \fn miniSetLedStates(uint8_t leds) @@ -299,12 +301,23 @@ void miniWheelClearDetections(void) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + last_detection_type_ret = WHEEL_ACTION_NONE; wheel_click_duration_counter = 0; wheel_click_return = RETURN_REL; + wheel_increment_armed = FALSE; wheel_cur_increment = 0; } } +/*! \fn miniGetLastReturnedAction(void) +* \brief Get the last returned action to another call +* \return See wheel_action_ret_t +*/ +RET_TYPE miniGetLastReturnedAction(void) +{ + return last_detection_type_ret; +} + /*! \fn miniGetWheelAction(void) * \brief Get current wheel action * \param wait_for_action Set to TRUE to wait for an action @@ -402,6 +415,7 @@ RET_TYPE miniGetWheelAction(uint8_t wait_for_action, uint8_t ignore_incdec) activityDetectedRoutine(); } + last_detection_type_ret = return_val; return return_val; } #endif \ No newline at end of file diff --git a/source_code/src/mini_inputs.h b/source_code/src/mini_inputs.h index 9ace3dbce..3d9c24c09 100644 --- a/source_code/src/mini_inputs.h +++ b/source_code/src/mini_inputs.h @@ -38,6 +38,7 @@ RET_TYPE miniGetWheelAction(uint8_t wait_for_action, uint8_t ignore_incdec); RET_TYPE isMiniDirectionPressed(uint8_t direction); void miniDirectionClearJoystickDetections(void); RET_TYPE getMiniDirectionJustPressed(void); +RET_TYPE miniGetLastReturnedAction(void); void miniDirectionClearDetections(void); int8_t getWheelCurrentIncrement(void); void miniSetLedStates(uint8_t leds);