/*! \fn getTouchedPositionAnswer(uint8_t led_mask) * \brief Use the capacitive interface to get quarter position * \param led_mask Led mask for the touchdetection routine * \return Number between 0 and 5 for valid pos, -1 otherwise */ int8_t getTouchedPositionAnswer(uint8_t led_mask) { #ifdef HARDWARE_V1 _delay_ms(2000); #endif #if defined(ALWAYS_ACCEPT_REQUESTS) || defined(HARDWARE_V1) // First quarter is discarded, it means we want yes or no! if (led_mask & LED_MASK_WHEEL_TLEFT) { return TOUCHPOS_RIGHT; } else { return TOUCHPOS_WHEEL_TLEFT; } #endif RET_TYPE touch_detect_result; // Switch on lights activityDetectedRoutine(); // Clear possible remaining detection touchDetectionRoutine(led_mask); touchWaitForWheelReleased(); touchClearCurrentDetections(); // Wait for a touch press, delay stored in eeprom (1024 is quite close to 1000 ;-) ) activateTimer(TIMER_USERINT, ((uint16_t)controlEepromParameter(getMooltipassParameterInEeprom(USER_INTER_TIMEOUT_PARAM), MIN_USER_INTER_DEL/1000, MAX_USER_INTER_DEL/1000)) << 10); do { // User interaction timeout or smartcard removed if ((hasTimerExpired(TIMER_USERINT, TRUE) == TIMER_EXPIRED) || (isSmartCardAbsent() == RETURN_OK)) { return -1; } touch_detect_result = touchDetectionRoutine(led_mask) & TOUCH_PRESS_MASK; } while (!touch_detect_result); // Did the user press one of the two touch buttons? if (touch_detect_result & RETURN_LEFT_PRESSED) { return TOUCHPOS_LEFT; } else if (touch_detect_result & RETURN_RIGHT_PRESSED) { return TOUCHPOS_RIGHT; } else { return (int8_t)getWheelTouchDetectionQuarter(); } }
/*! \fn touchDetectionRoutine(uint8_t led_mask) * \brief Touch detection routine * \param led_mask Mask containing which LEDs to switchoff * \return Touch detection result (see touch_detect_return_t) */ RET_TYPE touchDetectionRoutine(uint8_t led_mask) { RET_TYPE return_val = RETURN_NO_CHANGE; uint8_t keys_detection_status; uint8_t led_states[NB_KEYS]; uint8_t temp_bool = FALSE; uint8_t temp_uint; // Set the LEDs on by default memset((void*)led_states, AT42QT2120_OUTPUT_H_VAL, NB_KEYS); // Switch them off depending on mask for (temp_uint = 0; temp_uint < NB_KEYS; temp_uint++) { if (led_mask & (1 << temp_uint)) { led_states[temp_uint] = AT42QT2120_OUTPUT_L_VAL; } } if (isTouchChangeDetected()) { // Set temp bool to TRUE temp_bool = TRUE; // Read detection status register readDataFromTS(REG_AT42QT_DET_STAT, &keys_detection_status); // Unused byte that needs to be read readDataFromTS(REG_AT42QT_KEY_STAT1, &temp_uint); // If wheel is touched if (keys_detection_status & AT42QT2120_SDET_MASK) { // Get position and update global var readDataFromTS(REG_AT42QT_SLIDER_POS, &last_raw_wheel_position); // Update LED states led_states[getWheelTouchDetectionQuarter()] = AT42QT2120_OUTPUT_L_VAL; return_val |= RETURN_WHEEL_PRESSED; } else { return_val |= RETURN_WHEEL_RELEASED; } // Read button touched register readDataFromTS(REG_AT42QT_KEY_STAT2, &temp_uint); // If one button is touched if ((keys_detection_status & AT42QT2120_TDET_MASK) && !(keys_detection_status & AT42QT2120_SDET_MASK)) { if (temp_uint & 0x02) { // Left button led_states[TOUCHPOS_LEFT] = AT42QT2120_OUTPUT_L_VAL; return_val |= RETURN_LEFT_PRESSED; return_val |= RETURN_RIGHT_RELEASED; } else if(temp_uint & 0x08) { // Right button led_states[TOUCHPOS_RIGHT] = AT42QT2120_OUTPUT_L_VAL; return_val |= RETURN_RIGHT_PRESSED; return_val |= RETURN_LEFT_RELEASED; } else { return_val |= RETURN_PROX_DETECTION; } } else { return_val |= RETURN_PROX_RELEASED; return_val |= RETURN_LEFT_RELEASED; return_val |= RETURN_RIGHT_RELEASED; } // Switch on cathode if activity if (return_val & TOUCH_PRESS_MASK) { activityDetectedRoutine(); } // Touch inhibit logic if ((return_val & TOUCH_PRESS_MASK) == 0) { touch_inhibit = FALSE; } else if (touch_inhibit == TRUE) { return_val = RETURN_NO_CHANGE; } } // If there's a touch change or led mask has changed if ((temp_bool == TRUE) || (led_mask != last_led_mask)) { last_led_mask = led_mask; writeDataToTS(LEFT_LED_REGISTER, led_states[TOUCHPOS_LEFT]); writeDataToTS(RIGHT_LED_REGISTER, led_states[TOUCHPOS_RIGHT]); writeDataToTS(WHEEL_TLEFT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_TLEFT]); writeDataToTS(WHEEL_TRIGHT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_TRIGHT]); writeDataToTS(WHEEL_BLEFT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_BLEFT]); writeDataToTS(WHEEL_BRIGHT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_BRIGHT]); // In some rare cases LED state changes can create detections. In that case we add a small delay timerBasedDelayMs(2); touchClearCurrentDetections(); } return return_val; }
/*! \fn loginSelectionScreen(void) * \brief Screen displayed to let the user choose/find a login * \return Valid child node address or 0 otherwise */ uint16_t loginSelectionScreen(void) { char currentText[SEARCHTEXT_MAX_LENGTH+1]; uint8_t displayRefreshNeeded = TRUE; uint16_t ret_val = NODE_ADDR_NULL; uint8_t wasWheelReleased = TRUE; uint16_t tempParentAddresses[5]; uint8_t currentStringIndex = 0; uint8_t nbMatchedParents= 0; uint8_t finished = FALSE; RET_TYPE temp_rettype; uint8_t led_mask = 0; int8_t temp_int8; // Set current text to a last_matching_parent_addr = NODE_ADDR_NULL; last_matching_parent_number = 0; memcpy(currentText, "a\x00\x00\x00\x00", sizeof(currentText)); // Draw bitmap, display it and write active buffer oledBitmapDrawFlash(0, 0, BITMAP_LOGIN_FIND, 0); oledDisplayOtherBuffer(); oledWriteActiveBuffer(); // While the user hasn't chosen a credential while(!finished) { if (displayRefreshNeeded == TRUE) { nbMatchedParents = displayCurrentSearchLoginTexts(currentText, tempParentAddresses, currentStringIndex); displayRefreshNeeded = FALSE; // Light only the available choices and right arrow led_mask = 0; for (temp_int8 = nbMatchedParents; temp_int8 < 5; temp_int8++) { led_mask |= (1 << temp_int8); } } // Detect key touches temp_rettype = touchDetectionRoutine(led_mask); // Algo to differentiate a tap from a scroll if ((temp_rettype & RETURN_WHEEL_PRESSED) && (wasWheelReleased == TRUE)) { // We use the timer dedicated to touch inhibit for min activateTimer(TIMER_TOUCH_INHIBIT, TAP_MIN_DEL); // We use the timer dedicated to caps detect for max activateTimer(TIMER_CAPS, TAP_MAX_DEL); // This works because we use the same clearing flags wasWheelReleased = FALSE; } else if (temp_rettype & RETURN_WHEEL_RELEASED) { // Check if it's a tap and that the selected domain is valid if ((hasTimerExpired(TIMER_CAPS, FALSE) == TIMER_RUNNING) && (hasTimerExpired(TIMER_TOUCH_INHIBIT, FALSE) == TIMER_EXPIRED) && (getWheelTouchDetectionQuarter() < nbMatchedParents)) { ret_val = tempParentAddresses[getWheelTouchDetectionQuarter()]; finished = TRUE; } wasWheelReleased = TRUE; } // Send it to the touch wheel interface logic temp_int8 = touchWheelIntefaceLogic(temp_rettype); // Position increment / decrement if (temp_int8 != 0) { if ((currentText[currentStringIndex] == 0x7A) && (temp_int8 == 1)) { // z->0 wrap currentText[currentStringIndex] = 0x2F; } if ((currentText[currentStringIndex] == 0x39) && (temp_int8 == 1)) { // 9->a wrap currentText[currentStringIndex] = 0x60; } else if ((currentText[currentStringIndex] == 0x30) && (temp_int8 == -1)) { // 0->z wrap currentText[currentStringIndex] = 0x7B; } else if ((currentText[currentStringIndex] == 0x61) && (temp_int8 == -1)) { // a->9 wrap currentText[currentStringIndex] = 0x3A; } currentText[currentStringIndex] += temp_int8; displayRefreshNeeded = TRUE; } if ((isSmartCardAbsent() == RETURN_OK) || (hasTimerExpired(TIMER_USERINT, TRUE) == TIMER_EXPIRED)) { // Smartcard removed or no interaction for a while finished = TRUE; } else if (temp_rettype & RETURN_LEFT_PRESSED) { // Change search index if (currentStringIndex > 0) { currentText[currentStringIndex--] = 0; displayRefreshNeeded = TRUE; } else { finished = TRUE; } } else if ((temp_rettype & RETURN_RIGHT_PRESSED) && (nbMatchedParents > 4)) { // Change search index only if we need to... currentText[++currentStringIndex] = 'a'; displayRefreshNeeded = TRUE; } } // Set inactive buffer write by default oledWriteInactiveBuffer(); return ret_val; }
/*! \fn guiScreenLoop(uint8_t input_interface_result) * \brief Function called to handle screen changes * \param input_interface_result Touch detection result */ void guiScreenLoop(uint8_t input_interface_result) { #if defined(MINI_VERSION) // If no press, you can return! if ((input_interface_result == WHEEL_ACTION_NONE) || (currentScreen == SCREEN_DEFAULT_INSERTED_INVALID) || (currentScreen == SCREEN_DEFAULT_INSERTED_UNKNOWN)) { return; } if (currentScreen == SCREEN_DEFAULT_NINSERTED) { // No smart card inserted, ask the user to insert one guiDisplayInsertSmartCardScreenAndWait(); } else if (currentScreen == SCREEN_MEMORY_MGMT) { // Currently in memory management mode, tell the user to finish it via the plugin/app guiDisplayInformationOnScreenAndWait(ID_STRING_CLOSEMEMMGMT); guiGetBackToCurrentScreen(); } else if (currentScreen == SCREEN_DEFAULT_INSERTED_LCK) { // Locked screen and a detection happened, check that the user hasn't removed his card, launch unlocking process if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0) == RETURN_VCARD_OK)) { // User approved his pin currentScreen = SCREEN_DEFAULT_INSERTED_NLCK; } // Go to the new screen guiGetBackToCurrentScreen(); } else { if (input_interface_result == WHEEL_ACTION_UP) { // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h) if (currentScreen == SCREEN_LOCK) { currentScreen = SCREEN_SETTINGS; } else if (currentScreen == SCREEN_SETTINGS_CHANGE_PIN) { currentScreen = SCREEN_SETTINGS_ERASE; } else { currentScreen--; } // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h) for (uint8_t i = 0; i < NB_BMPS_PER_TRANSITION; i++) { oledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK+NB_BMPS_PER_TRANSITION-1-i, OLED_SCROLL_FLIP); timerBasedDelayMs(25); } } else if (input_interface_result == WHEEL_ACTION_DOWN) { // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h) for (uint8_t i = 0; i < NB_BMPS_PER_TRANSITION-1; i++) { oledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK+1+i, OLED_SCROLL_FLIP); timerBasedDelayMs(25); } if (currentScreen == SCREEN_SETTINGS) { currentScreen = SCREEN_LOCK; } else if (currentScreen == SCREEN_SETTINGS_ERASE) { currentScreen = SCREEN_SETTINGS_CHANGE_PIN; } else { currentScreen++; } oledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_FLIP); } else if (input_interface_result == WHEEL_ACTION_LONG_CLICK) { // Long press in main menu : lock, long press in settings menu: go back to login screen if ((currentScreen >= SCREEN_SETTINGS_CHANGE_PIN) && (currentScreen <= SCREEN_SETTINGS_ERASE)) { currentScreen = SCREEN_LOGIN; oledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP); } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; handleSmartcardRemoved(); guiGetBackToCurrentScreen(); } } else if (input_interface_result == WHEEL_ACTION_SHORT_CLICK) { switch(currentScreen) { case SCREEN_LOCK: { // User wants to lock his mooltipass currentScreen = SCREEN_DEFAULT_INSERTED_LCK; handleSmartcardRemoved(); guiGetBackToCurrentScreen(); break; } case SCREEN_LOGIN: { // User wants to go to the login menu if (getStartingParentAddress() != NODE_ADDR_NULL) { loginSelectLogic(); } else { guiDisplayInformationOnScreenAndWait(ID_STRING_NO_CREDS); } guiGetBackToCurrentScreen(); break; } case SCREEN_FAVORITES: { // User wants to go to the favorite menu favoritePickingLogic(); guiGetBackToCurrentScreen(); break; } case SCREEN_SETTINGS: { currentScreen = SCREEN_SETTINGS_CHANGE_PIN; oledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP); break; } case SCREEN_SETTINGS_HOME: { currentScreen = SCREEN_LOGIN; oledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP); break; } case SCREEN_SETTINGS_CHANGE_PIN: { // User wants to change his PIN code // Reauth user if (removeCardAndReAuthUser() == RETURN_OK) { // User approved his pin, ask his new one volatile uint16_t pin_code; if (guiAskForNewPin(&pin_code, ID_STRING_NEW_PINQ) == RETURN_NEW_PIN_OK) { // User successfully entered a new pin writeSecurityCode(&pin_code); // Inform of success guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_CHANGED); } else { // Inform of fail guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_NCGHANGED); } pin_code = 0x0000; } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; } guiGetBackToCurrentScreen(); break; } case SCREEN_SETTINGS_BACKUP: { // User wants to clone his smartcard volatile uint16_t pin_code; RET_TYPE temp_rettype; // Reauth user if (removeCardAndReAuthUser() == RETURN_OK) { // Ask for new pin temp_rettype = guiAskForNewPin(&pin_code, ID_STRING_PIN_NEW_CARD); if (temp_rettype == RETURN_NEW_PIN_OK) { // Start the cloning process if (cloneSmartCardProcess(&pin_code) == RETURN_OK) { // Well it worked.... } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_TGT_CARD_NBL); } pin_code = 0x0000; } else if (temp_rettype == RETURN_NEW_PIN_DIFF) { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_PIN_DIFF); } else { guiGetBackToCurrentScreen(); return; } } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_FAILED); } userViewDelay(); guiGetBackToCurrentScreen(); break; } case SCREEN_SETTINGS_ERASE: { // User wants to delete his profile in flash / eeprom.... if ((guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOUSURE)) == RETURN_OK) && (removeCardAndReAuthUser() == RETURN_OK) && (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOURLSURE)) == RETURN_OK)) { uint8_t currentuserid = getCurrentUserID(); guiDisplayProcessingScreen(); deleteCurrentUserFromFlash(); if (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_ERASE_TCARD)) == RETURN_OK) { guiDisplayProcessingScreen(); eraseSmartCard(); // Erase other smartcards while (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_OTHECARDFUSER)) == RETURN_OK) { // Ask the user to insert other smartcards guiDisplayInformationOnScreen(ID_STRING_INSERT_OTHER); // Wait for the user to remove and enter another smartcard while (isCardPlugged() != RETURN_JRELEASED); // Wait for the user to insert a new smart card while (isCardPlugged() != RETURN_JDETECT); guiDisplayProcessingScreen(); // Check the card type & ask user to enter his pin, check that the new user id loaded by validCardDetectedFunction is still the same if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0) == RETURN_VCARD_OK) && (currentuserid == getCurrentUserID())) { eraseSmartCard(); } } } // Delete LUT entries guiDisplayProcessingScreen(); deleteUserIdFromSMCUIDLUT(currentuserid); // Go to invalid screen currentScreen = SCREEN_DEFAULT_INSERTED_INVALID; } else { handleSmartcardRemoved(); currentScreen = SCREEN_DEFAULT_INSERTED_LCK; } userViewDelay(); guiGetBackToCurrentScreen(); break; } default: break; } } } #elif defined(HARDWARE_OLIVIER_V1) uint8_t state_machine_val = currentScreen; // If no press, you can return! if (!(input_interface_result & TOUCH_PRESS_MASK)) { return; } // Prevent touches until the user lifts his finger touchInhibitUntilRelease(); // Current screen is codded in the first 8 bytes, so we set the lowest 8 bytes to the detection quarter if (input_interface_result & RETURN_WHEEL_PRESSED) { state_machine_val |= getWheelTouchDetectionQuarter(); } else { state_machine_val |= 0x0F; } if (currentScreen == SCREEN_DEFAULT_NINSERTED) { // No smart card inserted, ask the user to insert one guiDisplayInsertSmartCardScreenAndWait(); } else if (currentScreen == SCREEN_MEMORY_MGMT) { // Currently in memory management mode, tell the user to finish it via the plugin/app guiDisplayInformationOnScreenAndWait(ID_STRING_CLOSEMEMMGMT); guiGetBackToCurrentScreen(); } else if (currentScreen == SCREEN_DEFAULT_INSERTED_LCK) { // Locked screen and a detection happened, check that the user hasn't removed his card, launch unlocking process if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0) == RETURN_VCARD_OK)) { // User approved his pin currentScreen = SCREEN_DEFAULT_INSERTED_NLCK; } // Go to the new screen guiGetBackToCurrentScreen(); } else { if (state_machine_val == (SCREEN_DEFAULT_INSERTED_NLCK|TOUCHPOS_WHEEL_BRIGHT)) { // User wants to lock his mooltipass currentScreen = SCREEN_DEFAULT_INSERTED_LCK; handleSmartcardRemoved(); guiGetBackToCurrentScreen(); } else if (state_machine_val == (SCREEN_DEFAULT_INSERTED_NLCK|TOUCHPOS_WHEEL_TRIGHT)) { // User wants to go to the settings menu currentScreen = SCREEN_SETTINGS; guiGetBackToCurrentScreen(); } else if (state_machine_val == (SCREEN_DEFAULT_INSERTED_NLCK|TOUCHPOS_WHEEL_BLEFT)) { // User wants to go to the favorite menu favoritePickingLogic(); guiGetBackToCurrentScreen(); } else if (state_machine_val == (SCREEN_DEFAULT_INSERTED_NLCK|TOUCHPOS_WHEEL_TLEFT)) { // User wants to go to the login menu if (getStartingParentAddress() != NODE_ADDR_NULL) { loginSelectLogic(); } else { guiDisplayInformationOnScreenAndWait(ID_STRING_NO_CREDS); } guiGetBackToCurrentScreen(); } else if (state_machine_val == (SCREEN_SETTINGS|TOUCHPOS_WHEEL_BLEFT)) { // User wants to delete his profile in flash / eeprom.... if ((guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOUSURE)) == RETURN_OK) && (removeCardAndReAuthUser() == RETURN_OK) && (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOURLSURE)) == RETURN_OK)) { uint8_t currentuserid = getCurrentUserID(); guiDisplayProcessingScreen(); deleteCurrentUserFromFlash(); if (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_ERASE_TCARD)) == RETURN_OK) { guiDisplayProcessingScreen(); eraseSmartCard(); // Erase other smartcards while (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_OTHECARDFUSER)) == RETURN_OK) { // Ask the user to insert other smartcards guiDisplayInformationOnScreen(ID_STRING_INSERT_OTHER); // Wait for the user to remove and enter another smartcard while (isCardPlugged() != RETURN_JRELEASED); // Wait for the user to insert a new smart card while (isCardPlugged() != RETURN_JDETECT); guiDisplayProcessingScreen(); // Check the card type & ask user to enter his pin, check that the new user id loaded by validCardDetectedFunction is still the same if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0) == RETURN_VCARD_OK) && (currentuserid == getCurrentUserID())) { eraseSmartCard(); } } } // Delete LUT entries guiDisplayProcessingScreen(); deleteUserIdFromSMCUIDLUT(currentuserid); // Go to invalid screen currentScreen = SCREEN_DEFAULT_INSERTED_INVALID; } else { handleSmartcardRemoved(); currentScreen = SCREEN_DEFAULT_INSERTED_LCK; } userViewDelay(); guiGetBackToCurrentScreen(); } else if (state_machine_val == (SCREEN_SETTINGS|TOUCHPOS_WHEEL_BRIGHT)) { // User wants to clone his smartcard volatile uint16_t pin_code; RET_TYPE temp_rettype; // Reauth user if (removeCardAndReAuthUser() == RETURN_OK) { // Ask for new pin temp_rettype = guiAskForNewPin(&pin_code, ID_STRING_PIN_NEW_CARD); if (temp_rettype == RETURN_NEW_PIN_OK) { // Start the cloning process if (cloneSmartCardProcess(&pin_code) == RETURN_OK) { // Well it worked.... } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_TGT_CARD_NBL); } pin_code = 0x0000; } else if (temp_rettype == RETURN_NEW_PIN_DIFF) { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_PIN_DIFF); } else { guiGetBackToCurrentScreen(); return; } } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_FAILED); } userViewDelay(); guiGetBackToCurrentScreen(); } else if (state_machine_val == (SCREEN_SETTINGS|TOUCHPOS_WHEEL_TLEFT)) { // User wants to go to the main menu currentScreen = SCREEN_DEFAULT_INSERTED_NLCK; guiGetBackToCurrentScreen(); } else if (state_machine_val == (SCREEN_SETTINGS|TOUCHPOS_WHEEL_TRIGHT)) { // User wants to change his PIN code // Reauth user if (removeCardAndReAuthUser() == RETURN_OK) { // User approved his pin, ask his new one volatile uint16_t pin_code; if (guiAskForNewPin(&pin_code, ID_STRING_NEW_PINQ) == RETURN_NEW_PIN_OK) { // User successfully entered a new pin writeSecurityCode(&pin_code); // Inform of success guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_CHANGED); } else { // Inform of fail guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_NCGHANGED); } pin_code = 0x0000; } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; } guiGetBackToCurrentScreen(); } } #endif }
/*! \fn getTouchedPositionAnswer(uint8_t led_mask) * \brief Use the capacitive interface to get quarter position * \param led_mask Led mask for the touchdetection routine * \return Number between 0 and 5 for valid pos, -1 otherwise */ int8_t getTouchedPositionAnswer(uint8_t led_mask) { #if defined(ALWAYS_ACCEPT_REQUESTS) // First quarter is discarded, it means we want yes or no! if (led_mask & LED_MASK_WHEEL_TLEFT) { return TOUCHPOS_RIGHT; } else { return TOUCHPOS_WHEEL_TLEFT; } #endif uint8_t incomingData[RAWHID_TX_SIZE]; RET_TYPE touch_detect_result; // Switch on lights activityDetectedRoutine(); // Clear possible remaining detection touchDetectionRoutine(led_mask); // Additional masking in case we only want left / right uint8_t additional_mask = 0xFF; if (led_mask == LED_MASK_WHEEL) { additional_mask = RETURN_LEFT_PRESSED | RETURN_RIGHT_PRESSED; } // Wait for a touch press do { // User interaction timeout or smartcard removed if ((hasTimerExpired(TIMER_USERINT, TRUE) == TIMER_EXPIRED) || (isSmartCardAbsent() == RETURN_OK)) { 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 (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); } } touch_detect_result = touchDetectionRoutine(led_mask) & TOUCH_PRESS_MASK & additional_mask; } while (!touch_detect_result); // Prevent touches until the user lifts his finger touchInhibitUntilRelease(); // Did the user press one of the two touch buttons? if (touch_detect_result & RETURN_LEFT_PRESSED) { return TOUCHPOS_LEFT; } else if (touch_detect_result & RETURN_RIGHT_PRESSED) { return TOUCHPOS_RIGHT; } else { return (int8_t)getWheelTouchDetectionQuarter(); } }
/*! \fn touchDetectionRoutine(uint8_t led_mask) * \brief Touch detection routine * \param led_mask Mask containing which LEDs to switchoff * \return Touch detection result (see touch_detect_return_t) */ uint8_t mooltipass_touch_sensing::touchDetectionRoutine(uint8_t led_mask) { uint8_t return_val = RETURN_NO_CHANGE; uint8_t keys_detection_status; uint8_t led_states[NB_KEYS]; uint8_t temp_bool = false; uint8_t temp_uint; // Set the LEDs on by default memset((void*)led_states, AT42QT2120_OUTPUT_H_VAL, NB_KEYS); // Switch them off depending on mask for (temp_uint = 0; temp_uint < NB_KEYS; temp_uint++) { if (led_mask & (1 << temp_uint)) { led_states[temp_uint] = AT42QT2120_OUTPUT_L_VAL; } } if (isTouchChangeDetected()) { // Set temp bool to true temp_bool = true; // Read detection status register readDataFromTS(REG_AT42QT_DET_STAT, &keys_detection_status); // Unused byte that needs to be read readDataFromTS(REG_AT42QT_KEY_STAT1, &temp_uint); // If wheel is touched if (keys_detection_status & AT42QT2120_SDET_MASK) { // Get position and update global var readDataFromTS(REG_AT42QT_SLIDER_POS, &last_raw_wheel_position); // Update LED states led_states[getWheelTouchDetectionQuarter()] = AT42QT2120_OUTPUT_L_VAL; return_val |= RETURN_WHEEL_PRESSED; } else { return_val |= RETURN_WHEEL_RELEASED; } // Read button touched register readDataFromTS(REG_AT42QT_KEY_STAT2, &temp_uint); // If one button is touched if ((keys_detection_status & AT42QT2120_TDET_MASK) && !(keys_detection_status & AT42QT2120_SDET_MASK)) { if (temp_uint & 0x02) { // Left button led_states[TOUCHPOS_LEFT] = AT42QT2120_OUTPUT_L_VAL; return_val |= RETURN_LEFT_PRESSED; return_val |= RETURN_RIGHT_RELEASED; } else if(temp_uint & 0x08) { // Right button led_states[TOUCHPOS_RIGHT] = AT42QT2120_OUTPUT_L_VAL; return_val |= RETURN_RIGHT_PRESSED; return_val |= RETURN_LEFT_RELEASED; } else { return_val |= RETURN_PROX_DETECTION; } } else { return_val |= RETURN_PROX_RELEASED; return_val |= RETURN_LEFT_RELEASED; return_val |= RETURN_RIGHT_RELEASED; } // Switch on cathode if activity if (return_val & TOUCH_PRESS_MASK) { //activityDetectedRoutine(); } } // If there's a touch change or led mask has changed if ((temp_bool == true) || (led_mask != last_led_mask)) { last_led_mask = led_mask; writeDataToTS(LEFT_LED_REGISTER, led_states[TOUCHPOS_LEFT]); writeDataToTS(RIGHT_LED_REGISTER, led_states[TOUCHPOS_RIGHT]); writeDataToTS(WHEEL_TLEFT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_TLEFT]); writeDataToTS(WHEEL_TRIGHT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_TRIGHT]); writeDataToTS(WHEEL_BLEFT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_BLEFT]); writeDataToTS(WHEEL_BRIGHT_LED_REGISTER, led_states[TOUCHPOS_WHEEL_BRIGHT]); } return return_val; }