blob: fafb7875e22ee1b906c86cc56d71f6e21b4fdf16 [file] [log] [blame]
Reut Zysmanff6bab92016-02-09 14:06:31 +02001/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
Amit Blay6281ebc2015-01-11 14:44:08 +02002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <dev/fbcon.h>
31#include <target.h>
32#include <mmc.h>
33#include <partition_parser.h>
34#include <stdlib.h>
Reut Zysman18411272015-02-09 13:47:27 +020035#include <string.h>
Amit Blay6281ebc2015-01-11 14:44:08 +020036#include "mdtp.h"
Reut Zysman561d81a2015-08-26 17:37:28 +030037#include "mdtp_defs.h"
Reut Zysmanff6bab92016-02-09 14:06:31 +020038#include "mdtp_fs.h"
39#include <display_menu.h>
Reut Zysman18411272015-02-09 13:47:27 +020040
41// Image releative locations
42#define ERROR_MESSAGE_RELATIVE_Y_LOCATION (0.18)
43#define MAIN_TEXT_RELATIVE_Y_LOCATION (0.33)
44#define PIN_RELATIVE_Y_LOCATION (0.47)
45#define PIN_TEXT_RELATIVE_Y_LOCATION (0.57)
46#define OK_BUTTON_RELATIVE_Y_LOCATION (0.75)
47#define OK_TEXT_RELATIVE_Y_LOCATION (0.82)
48
Reut Zysman18411272015-02-09 13:47:27 +020049#define MDTP_PRESSING_DELAY_MSEC (400)
50#define MDTP_MAX_IMAGE_SIZE (1183000) //size in bytes, includes some extra bytes since we round up to block size in read
51#define RGB888_BLACK (0x000000)
52#define BITS_PER_BYTE (8)
53
54
Amit Blay8e2731c2015-04-28 21:54:55 +030055#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width) (((screen_width)-(image_width))/2)
Reut Zysman18411272015-02-09 13:47:27 +020056
Amit Blay6281ebc2015-01-11 14:44:08 +020057extern void mdelay(unsigned msecs);
Reut Zysman18411272015-02-09 13:47:27 +020058extern uint32_t target_volume_up();
59extern uint32_t target_volume_down();
Amit Blayf43af752015-11-10 19:13:37 +020060extern int msm_display_on();
Amit Blay6281ebc2015-01-11 14:44:08 +020061
Reut Zysman18411272015-02-09 13:47:27 +020062struct mdtp_fbimage {
63 uint32_t width;
64 uint32_t height;
65 uint8_t image[MDTP_MAX_IMAGE_SIZE];
66};
Amit Blay6281ebc2015-01-11 14:44:08 +020067
Reut Zysman18411272015-02-09 13:47:27 +020068/*----------------------------------------------------------------------------
69 * Global Variables
70 * -------------------------------------------------------------------------*/
Amit Blay6281ebc2015-01-11 14:44:08 +020071
Amir Kotzer20716f12016-02-24 10:31:18 +020072static uint32_t g_pin_frames_x_location[MDTP_PIN_LEN] = {0};
Reut Zysman18411272015-02-09 13:47:27 +020073static uint32_t g_pin_frames_y_location = 0;
74
75static bool g_initial_screen_displayed = false;
76
Rami Butsteinfaecf7f2015-06-04 16:39:30 +030077static struct mdtp_fbimage *g_mdtp_header = NULL;
Reut Zysman18411272015-02-09 13:47:27 +020078static struct fbcon_config *fb_config = NULL;
79
Reut Zysman561d81a2015-08-26 17:37:28 +030080
Reut Zysman18411272015-02-09 13:47:27 +020081/*----------------------------------------------------------------------------
82 * Local Functions
83 * -------------------------------------------------------------------------*/
84
85/**
Rami Butsteinfaecf7f2015-06-04 16:39:30 +030086 * Allocate mdtp image
87 */
88static void alloc_mdtp_image() {
89 if (!g_mdtp_header) {
90 g_mdtp_header = (struct mdtp_fbimage *)malloc(sizeof(struct mdtp_fbimage));
91 ASSERT(g_mdtp_header);
92 }
93}
94
95/**
96 * Free mdtp image
97 */
98void free_mdtp_image() {
99 if (g_mdtp_header) {
100 free(g_mdtp_header);
101 g_mdtp_header = NULL;
102 }
103}
104
105/**
Reut Zysman18411272015-02-09 13:47:27 +0200106 * Load images from EMMC
107 */
108static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height)
Amit Blay6281ebc2015-01-11 14:44:08 +0200109{
110 int index = INVALID_PTN;
111 unsigned long long ptn = 0;
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300112 struct mdtp_fbimage *logo = g_mdtp_header;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200113 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +0200114
115 index = partition_get_index("mdtp");
116 if (index == 0) {
117 dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
118 return NULL;
119 }
120
121 ptn = partition_get_offset(index);
122 if (ptn == 0) {
123 dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
124 return NULL;
125 }
126
Reut Zysman18411272015-02-09 13:47:27 +0200127 if (fb_config)
Amit Blay6281ebc2015-01-11 14:44:08 +0200128 {
Reut Zysman18411272015-02-09 13:47:27 +0200129 uint8_t *base = logo->image;
Amit Blay8e2731c2015-04-28 21:54:55 +0300130 unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
Amit Blay6281ebc2015-01-11 14:44:08 +0200131
Amit Blay8e2731c2015-04-28 21:54:55 +0300132 if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) {
Amit Blay6281ebc2015-01-11 14:44:08 +0200133 fbcon_clear();
134 dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
135 return NULL;
136 }
Amit Blay4418fb42015-05-05 08:45:13 +0300137
Reut Zysman18411272015-02-09 13:47:27 +0200138 logo->width = width;
139 logo->height = height;
Amit Blay6281ebc2015-01-11 14:44:08 +0200140 }
141
142 return logo;
143}
144
Reut Zysman18411272015-02-09 13:47:27 +0200145/**
146 * flush fbcon display
147 *
148 * The function is duplicated from fbcon.c
149 */
150static void fbcon_flush(void)
Amit Blay6281ebc2015-01-11 14:44:08 +0200151{
Reut Zysman18411272015-02-09 13:47:27 +0200152 if (fb_config->update_start)
153 fb_config->update_start();
154 if (fb_config->update_done)
155 while (!fb_config->update_done());
156}
Amit Blay6281ebc2015-01-11 14:44:08 +0200157
Reut Zysman18411272015-02-09 13:47:27 +0200158/**
159 * Clear complete section on the screen.
160 * The section is of section_height, and is located from the y
161 * coordinate and down.
162 */
163static void fbcon_clear_section(uint32_t y, uint32_t section_height)
164{
165 unsigned image_base;
166 unsigned bytes_per_bpp;
Amit Blay6281ebc2015-01-11 14:44:08 +0200167
Reut Zysman18411272015-02-09 13:47:27 +0200168 if (fb_config)
Amit Blay6281ebc2015-01-11 14:44:08 +0200169 {
Reut Zysman18411272015-02-09 13:47:27 +0200170 image_base = (y *(fb_config->width));
171 bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
Amit Blay6281ebc2015-01-11 14:44:08 +0200172
Reut Zysman18411272015-02-09 13:47:27 +0200173 unsigned count = fb_config->width*section_height;
174 memset(fb_config->base + image_base*bytes_per_bpp, RGB888_BLACK, count*bytes_per_bpp);
175
176 fbcon_flush();
Amit Blay6281ebc2015-01-11 14:44:08 +0200177 }
Reut Zysman18411272015-02-09 13:47:27 +0200178 else
Amit Blay6281ebc2015-01-11 14:44:08 +0200179 {
Reut Zysman18411272015-02-09 13:47:27 +0200180 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300181 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200182 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200183}
184
Reut Zysman18411272015-02-09 13:47:27 +0200185/**
186 * Put image at a specific (x,y) location on the screen.
187 * Duplicated from fbcon.c, with modifications to allow (x,y) location (instead of a centered image),
188 * and display bmp images properly (order of copying the lines to the screen was reversed)
189 */
190static void fbcon_putImage_in_location(struct mdtp_fbimage *fbimg, uint32_t x, uint32_t y)
Amit Blay6281ebc2015-01-11 14:44:08 +0200191{
Reut Zysman18411272015-02-09 13:47:27 +0200192 unsigned i = 0;
193 unsigned bytes_per_bpp;
194 unsigned image_base;
195 unsigned width, pitch, height;
196 unsigned char *logo_base = NULL;
Amit Blay6281ebc2015-01-11 14:44:08 +0200197
Reut Zysman18411272015-02-09 13:47:27 +0200198 if (!fb_config) {
199 dprintf(CRITICAL,"ERROR: NULL configuration, image cannot be displayed\n");
200 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200201 }
202
Reut Zysman18411272015-02-09 13:47:27 +0200203 if(fbimg) {
204 width = pitch = fbimg->width;
205 height = fbimg->height;
206 logo_base = (unsigned char *)fbimg->image;
207 }
208 else {
209 dprintf(CRITICAL,"ERROR: invalid image struct\n");
210 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200211 }
212
Reut Zysman18411272015-02-09 13:47:27 +0200213 bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
214
215#if DISPLAY_TYPE_MIPI
216 if (bytes_per_bpp == 3)
Amit Blay6281ebc2015-01-11 14:44:08 +0200217 {
Reut Zysman18411272015-02-09 13:47:27 +0200218 if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
Reut Zysman18411272015-02-09 13:47:27 +0200219 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300220 dprintf(CRITICAL,"ERROR: full screen image, cannot be displayed\n");
221 return;
222 }
223
224 if (fbimg->width > fb_config->width || fbimg->height > fb_config->height ||
225 (x > (fb_config->width - fbimg->width)) || (y > (fb_config->height - fbimg->height)))
226 {
227 dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen or exceeds its margins\n");
Reut Zysman18411272015-02-09 13:47:27 +0200228 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200229 }
Reut Zysman18411272015-02-09 13:47:27 +0200230
231 image_base = ( (y *(fb_config->width)) + x);
232 for (i = 0; i < height; i++) {
233 memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
234 logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
235 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200236 }
Amit Blay8e2731c2015-04-28 21:54:55 +0300237 else
238 {
239 dprintf(CRITICAL,"ERROR: invalid bpp value\n");
240 display_error_msg(); /* This will never return */
241 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200242
Amit Blay4418fb42015-05-05 08:45:13 +0300243 /* Flush the contents to memory before giving the data to dma */
244 arch_clean_invalidate_cache_range((addr_t) fb_config->base, (fb_config->height * fb_config->width * bytes_per_bpp));
245
Reut Zysman18411272015-02-09 13:47:27 +0200246 fbcon_flush();
Amit Blayf43af752015-11-10 19:13:37 +0200247 msm_display_on();
Reut Zysman18411272015-02-09 13:47:27 +0200248
Reut Zysman18411272015-02-09 13:47:27 +0200249#endif
Amit Blay6281ebc2015-01-11 14:44:08 +0200250}
251
Reut Zysman18411272015-02-09 13:47:27 +0200252/**
253 * Display main error message
254 */
255static int display_error_message()
Amit Blay6281ebc2015-01-11 14:44:08 +0200256{
Reut Zysman18411272015-02-09 13:47:27 +0200257 struct mdtp_fbimage *fbimg;
Amit Blay6281ebc2015-01-11 14:44:08 +0200258
Reut Zysman18411272015-02-09 13:47:27 +0200259 if (fb_config)
260 {
Reut Zysmanff6bab92016-02-09 14:06:31 +0200261 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ALERT_MESSAGE),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200262 uint32_t y = ((fb_config->height)*ERROR_MESSAGE_RELATIVE_Y_LOCATION);
Reut Zysmanff6bab92016-02-09 14:06:31 +0200263 fbimg = mdtp_read_mmc_image(get_image_offset(ALERT_MESSAGE),get_image_width(ALERT_MESSAGE), get_image_height(ALERT_MESSAGE));
Reut Zysman18411272015-02-09 13:47:27 +0200264 if (NULL == fbimg)
265 {
266 dprintf(CRITICAL,"ERROR: failed to read error image from mmc\n");
267 return -1;
268 }
269
270 fbcon_putImage_in_location(fbimg, x, y);
271
272 return 0;
273 }
274 else
275 {
276 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
277 return -1;
278 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200279}
280
Reut Zysman18411272015-02-09 13:47:27 +0200281/**
282 * Read from mmc the image in the given offset, of the given width and height.
283 * Then, display the image on the screen in the given (x,y) location.
284 */
285static void display_image(uint32_t offset, uint32_t width, uint32_t height, uint32_t x, uint32_t y)
Amit Blay6281ebc2015-01-11 14:44:08 +0200286{
Reut Zysman18411272015-02-09 13:47:27 +0200287 struct mdtp_fbimage *fbimg;
Amit Blay6281ebc2015-01-11 14:44:08 +0200288
Reut Zysman18411272015-02-09 13:47:27 +0200289 if (fb_config)
290 {
291 fbimg = mdtp_read_mmc_image(offset, width, height);
292 if (NULL == fbimg)
293 {
294 dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300295 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200296 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200297
Reut Zysman18411272015-02-09 13:47:27 +0200298 fbcon_putImage_in_location(fbimg, x, y);
299 }
300 else
301 {
302 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300303 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200304 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200305}
306
Reut Zysman18411272015-02-09 13:47:27 +0200307/**
308 * Display initial delay message
309 */
310static void display_initial_delay()
Amit Blay6281ebc2015-01-11 14:44:08 +0200311{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200312 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_5SECONDS),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200313 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200314 display_image(get_image_offset(MAINTEXT_5SECONDS), get_image_width(MAINTEXT_5SECONDS), get_image_height(MAINTEXT_5SECONDS), x, y);
Amit Blay6281ebc2015-01-11 14:44:08 +0200315}
316
Reut Zysman18411272015-02-09 13:47:27 +0200317/**
318 * Display "enter PIN" message
319 */
320static void display_enter_pin()
Amit Blay6281ebc2015-01-11 14:44:08 +0200321{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200322 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_ENTERPIN),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200323 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200324 display_image(get_image_offset(MAINTEXT_ENTERPIN), get_image_width(MAINTEXT_ENTERPIN), get_image_height(MAINTEXT_ENTERPIN), x, y);
Amit Blay6281ebc2015-01-11 14:44:08 +0200325}
326
Reut Zysman18411272015-02-09 13:47:27 +0200327/**
328 * Display invalid PIN message
329 */
330static void display_invalid_pin()
Amit Blay6281ebc2015-01-11 14:44:08 +0200331{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200332 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_INCORRECTPIN),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200333 uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
Amit Blay6281ebc2015-01-11 14:44:08 +0200334
Reut Zysmanff6bab92016-02-09 14:06:31 +0200335 display_image(get_image_offset(MAINTEXT_INCORRECTPIN), get_image_width(MAINTEXT_INCORRECTPIN), get_image_height(MAINTEXT_INCORRECTPIN), x, y);
Amit Blay6281ebc2015-01-11 14:44:08 +0200336}
337
Reut Zysman18411272015-02-09 13:47:27 +0200338/**
339 * Clear digits instructions
340 */
341static void display_digits_instructions()
Amit Blay6281ebc2015-01-11 14:44:08 +0200342{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200343 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(PINTEXT),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200344 uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
345
Reut Zysmanff6bab92016-02-09 14:06:31 +0200346 display_image(get_image_offset(PINTEXT), get_image_width(PINTEXT), get_image_height(PINTEXT), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200347}
348
349/**
350 * Clear digits instructions
351 */
352static void clear_digits_instructions()
353{
354 uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200355 fbcon_clear_section(y, get_image_height(PINTEXT));
Reut Zysman18411272015-02-09 13:47:27 +0200356}
357
358/**
359 * Display a digit as un-selected.
360 */
361static void display_digit(uint32_t x, uint32_t y, uint32_t digit)
362{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200363 display_image(get_image_offset(PIN_UNSELECTED_0 + digit),
364 get_image_width(PIN_UNSELECTED_0 + digit), get_image_height(PIN_UNSELECTED_0 + digit), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200365}
366
367/**
368 * Display a digit as selected.
369 */
370static void display_selected_digit(uint32_t x, uint32_t y, uint32_t digit)
371{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200372 display_image(get_image_offset(PIN_SELECTED_0 + digit),
373 get_image_width(PIN_SELECTED_0 + digit),
374 get_image_height(PIN_SELECTED_0 + digit), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200375}
376
377/**
378 * Display OK button as un-selected.
379 */
380static void display_ok_button()
381{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200382 uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(get_image_width(BTN_OK_OFF),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200383 uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
384
Reut Zysmanff6bab92016-02-09 14:06:31 +0200385 display_image(get_image_offset(BTN_OK_OFF), get_image_width(BTN_OK_OFF),get_image_height(BTN_OK_OFF), ok_x, ok_y);
Reut Zysman18411272015-02-09 13:47:27 +0200386}
387
388/**
389 * Display OK button as selected.
390 */
391static void display_selected_ok_button()
392{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200393 uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(get_image_width(BTN_OK_ON),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200394 uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;
395
Reut Zysmanff6bab92016-02-09 14:06:31 +0200396 display_image(get_image_offset(BTN_OK_ON), get_image_width(BTN_OK_ON), get_image_height(BTN_OK_ON), ok_x, ok_y);
Reut Zysman18411272015-02-09 13:47:27 +0200397}
398
Reut Zysmanff6bab92016-02-09 14:06:31 +0200399
Reut Zysman18411272015-02-09 13:47:27 +0200400/**
401 * Display the instructions for the OK button.
402 */
403static void display_pin_instructions()
404{
Reut Zysmanff6bab92016-02-09 14:06:31 +0200405 uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ACCEPTEDIT_TEXT),fb_config->width);
Reut Zysman18411272015-02-09 13:47:27 +0200406 uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
407
Reut Zysmanff6bab92016-02-09 14:06:31 +0200408 display_image(get_image_offset(ACCEPTEDIT_TEXT), get_image_width(ACCEPTEDIT_TEXT), get_image_height(ACCEPTEDIT_TEXT), x, y);
Reut Zysman18411272015-02-09 13:47:27 +0200409}
410
411/**
412 * Clear the instructions for the OK button.
413 */
414static void clear_pin_message()
415{
416 uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;
417
Reut Zysmanff6bab92016-02-09 14:06:31 +0200418 fbcon_clear_section(y,get_image_height(ACCEPTEDIT_TEXT));
Reut Zysman33512bc2015-08-09 19:17:09 +0300419}
420
421/**
422 * Initialize data structures required for MDTP UI.
423 */
424static void init_mdtp_ui_data()
425{
426 fb_config = fbcon_display();
427 alloc_mdtp_image();
Reut Zysman18411272015-02-09 13:47:27 +0200428}
429
430/**
431 * Display the basic layout of the screen (done only once).
432 */
433static void display_initial_screen(uint32_t pin_length)
434{
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300435 if (g_initial_screen_displayed == true)
Reut Zysman18411272015-02-09 13:47:27 +0200436 return;
437
Reut Zysman33512bc2015-08-09 19:17:09 +0300438 init_mdtp_ui_data();
Reut Zysman18411272015-02-09 13:47:27 +0200439
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300440 if (fb_config)
Reut Zysman18411272015-02-09 13:47:27 +0200441 {
442 fbcon_clear();
443
444 if (display_error_message())
Amit Blay8e2731c2015-04-28 21:54:55 +0300445 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200446 display_initial_delay();
447
448 mdelay(INITIAL_DELAY_MSECONDS);
449
450 g_pin_frames_y_location = ((fb_config->height)*PIN_RELATIVE_Y_LOCATION);
451
Reut Zysmanff6bab92016-02-09 14:06:31 +0200452 uint32_t total_pin_length = pin_length*get_image_width(PIN_UNSELECTED_0) + mdtp_fs_get_param(DIGIT_SPACE)*(pin_length - 1);
Reut Zysman18411272015-02-09 13:47:27 +0200453 uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
454
Amit Blay8e2731c2015-04-28 21:54:55 +0300455 for (uint32_t i=0; i<pin_length; i++)
Reut Zysman18411272015-02-09 13:47:27 +0200456 {
Reut Zysmanff6bab92016-02-09 14:06:31 +0200457 g_pin_frames_x_location[i] = complete_pin_centered + i*(mdtp_fs_get_param(DIGIT_SPACE) + get_image_width(PIN_UNSELECTED_0));
Reut Zysman18411272015-02-09 13:47:27 +0200458 }
459
Amit Blay8e2731c2015-04-28 21:54:55 +0300460 for (uint32_t i=0; i<pin_length; i++)
Reut Zysman18411272015-02-09 13:47:27 +0200461 {
462 display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
463 }
464
465 display_ok_button();
466
467 g_initial_screen_displayed = true;
468 }
469 else
470 {
471 dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300472 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200473 }
474}
475
476/**
477 * Display the recovery PIN screen and set received buffer
478 * with the PIN the user has entered.
479 * The entered PIN will be validated by the calling function.
480 */
481static void display_get_pin_interface(char *entered_pin, uint32_t pin_length)
482{
483 uint32_t previous_position = 0, current_position = 0;
484
485 display_initial_screen(pin_length);
486 display_enter_pin();
487
488 // Convert ascii to digits
489 for (uint32_t i=0; i<pin_length; i++)
490 {
491 entered_pin[i] -= '0';
492 }
493 display_selected_digit(g_pin_frames_x_location[0], g_pin_frames_y_location, entered_pin[0]);
494 display_digits_instructions();
Amit Blay6281ebc2015-01-11 14:44:08 +0200495
496 while (1)
497 {
Reut Zysman18411272015-02-09 13:47:27 +0200498 if (target_volume_up())
Amit Blay6281ebc2015-01-11 14:44:08 +0200499 {
Reut Zysman18411272015-02-09 13:47:27 +0200500 // current position is the OK button
501 if (current_position == pin_length)
502 {
503 // Convert digits to ascii and
504 // validate entered PIN in the calling function
505 for (uint32_t i=0; i<pin_length; i++)
506 {
507 entered_pin[i] += '0';
508 }
509 return;
510 }
511
512 // current position is a PIN slot
513 entered_pin[current_position] = (entered_pin[current_position]+1) % 10;
514 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
515 mdelay(MDTP_PRESSING_DELAY_MSEC);
516 }
517 if (target_volume_down())
518 {
519 previous_position = current_position;
520 current_position = (current_position+1) % (pin_length+1);
521
522 // previous position was the OK button
523 if (previous_position == pin_length)
524 {
525 clear_pin_message();
526 display_ok_button();
527
528 display_digits_instructions();
529 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
530
531 }
532
533 // current position is the OK button
534 else if (current_position == pin_length)
535 {
536 display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
537 clear_digits_instructions();
538
539 display_selected_ok_button();
540 display_pin_instructions();
541 }
542
543 // both the previous and the current positions are PIN slots
544 else
545 {
546 display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
547
548 display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
549 }
550
551 mdelay(MDTP_PRESSING_DELAY_MSEC);
Amit Blay6281ebc2015-01-11 14:44:08 +0200552 }
553 }
Reut Zysman18411272015-02-09 13:47:27 +0200554}
555
556/*----------------------------------------------------------------------------
557 * External Functions
558 * -------------------------------------------------------------------------*/
559
560/**
561 * Display the recovery PIN screen and set received buffer
562 * with the PIN the user has entered.
563 */
564void get_pin_from_user(char *entered_pin, uint32_t pin_length)
565{
566 display_get_pin_interface(entered_pin, pin_length);
Amit Blay6281ebc2015-01-11 14:44:08 +0200567
568 return;
569}
570
Reut Zysman18411272015-02-09 13:47:27 +0200571/**
572 * User has entered invalid PIN, display error message and
573 * allow the user to try again.
574 */
575void display_invalid_pin_msg()
Amit Blay6281ebc2015-01-11 14:44:08 +0200576{
Reut Zysman18411272015-02-09 13:47:27 +0200577 clear_pin_message();
578 display_ok_button();
579
580 display_invalid_pin();
581
582 mdelay(INVALID_PIN_DELAY_MSECONDS);
Amit Blay6281ebc2015-01-11 14:44:08 +0200583}
584
Reut Zysman18411272015-02-09 13:47:27 +0200585/**
586 * Display error message and stop boot process.
587 */
588void display_error_msg()
Amit Blay6281ebc2015-01-11 14:44:08 +0200589{
Reut Zysman33512bc2015-08-09 19:17:09 +0300590 init_mdtp_ui_data();
Amit Blay8e2731c2015-04-28 21:54:55 +0300591
592 if (fb_config)
593 {
594 fbcon_clear();
595 display_error_message(); // No point in checking the return value here
596 }
Reut Zysman18411272015-02-09 13:47:27 +0200597
598 // Invalid state. Nothing to be done but contacting the OEM.
599 // Stop boot process.
600 dprintf(CRITICAL,"ERROR: blocking boot process\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300601 for(;;);
Amit Blay6281ebc2015-01-11 14:44:08 +0200602}
603
Reut Zysmanff6bab92016-02-09 14:06:31 +0200604/**
605 * Display error message in case mdtp image is corrupted and stop boot process.
606 */
607void display_error_msg_mdtp()
608{
609 int big_factor = 8; // Font size
610 char* str = "Device unable to boot";
611 char* str2 = "\nError - mdtp image is corrupted\n";
612 fbcon_clear();
613 while(*str != 0) {
614 fbcon_putc_factor(*str++, FBCON_COMMON_MSG, big_factor);
615 }
616 fbcon_draw_line(FBCON_COMMON_MSG);
617 while(*str2 != 0) {
618 fbcon_putc_factor(*str2++, FBCON_COMMON_MSG, big_factor);
619 }
620 fbcon_draw_line(FBCON_COMMON_MSG);
621
622 // Invalid state. Nothing to be done but contacting the OEM.
623 // Stop boot process.
624 dprintf(CRITICAL,"ERROR: blocking boot process - mdtp image corrupted\n");
625 for(;;);
626
627}
628