Skip to content

Commit

Permalink
Update NBGL serialization for TTYT
Browse files Browse the repository at this point in the history
  • Loading branch information
nroggeman-ledger committed Oct 13, 2023
1 parent 54bf657 commit 562460d
Show file tree
Hide file tree
Showing 11 changed files with 441 additions and 179 deletions.
1 change: 1 addition & 0 deletions lib_nbgl/include/nbgl_obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ void nbgl_objAllowDrawing(bool enable);
void nbgl_objPoolRelease(uint8_t layer);
nbgl_obj_t *nbgl_objPoolGet(nbgl_obj_type_t type, uint8_t layer);
nbgl_obj_t *nbgl_objPoolGetPrevious(nbgl_obj_t *obj, uint8_t layer);
uint8_t nbgl_objPoolGetId(nbgl_obj_t *obj);
int nbgl_objPoolGetArray(nbgl_obj_type_t type,
uint8_t nbObjs,
uint8_t layer,
Expand Down
4 changes: 2 additions & 2 deletions lib_nbgl/serialization/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

INC := -I ../include/ -I ../../lib_ux_stax/
INC := -I . -I ../include
DEFINES := -DLINUX_SIMU -DHAVE_LANGUAGE_PACK -DNBGL_GENERATE_DATA_TEST

default: generate_data_test.c
gcc $(INC) generate_data_test.c $(DEFINES) ../src/nbgl_serialize.c -o generate_data_test
gcc $(INC) generate_data_test.c $(DEFINES) ../src/nbgl_serialize.c ../src/nbgl_obj_pool.c -o generate_data_test

run_test: default
./generate_data_test > data_test.txt
Expand Down
2 changes: 1 addition & 1 deletion lib_nbgl/serialization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Deserialize raw bytes into an Nbgl event:
```python
>>> from nbgl_lib import deserialize_nbgl_bytes
>>> data = bytes.fromhex("000601f403e800ff003201000301020403015465737420627574746f6e00")
>>> data = bytes.fromhex("00010501f403e800ff003201000301020403015465737420627574746f6e00")
>>> nbgl_event = deserialize_nbgl_bytes(data)
>>> nbgl_event
NbglDrawObjectEvent(obj=NbglButton(area=NbglArea(width=255, height=50, x0=500, y0=1000, background_color=<NbglColor.DARK_GRAY: 1>, bpp=<NbglBpp.BPP_1: 0>), inner_color=<NbglColor.WHITE: 3>, border_color=<NbglColor.DARK_GRAY: 1>, foreground_color=<NbglColor.LIGHT_GRAY: 2>, radius=<NbglRadius.RADIUS_24_PIXELS: 4>, font_id=<NbglFontId.BAGL_FONT_HM_ALPHA_MONO_MEDIUM_32px: 3>, localized=True, text='Test button'))
Expand Down
243 changes: 137 additions & 106 deletions lib_nbgl/serialization/generate_data_test.c

Large diffs are not rendered by default.

77 changes: 54 additions & 23 deletions lib_nbgl/serialization/nbgl_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,20 @@ class NbglKeyboardMode(IntEnum):
class NbglObjType(IntEnum):
SCREEN, = 0, # Main screen
CONTAINER, = 1, # Empty container
PANEL, = 2, # Container with special border
IMAGE, = 3, # Bitmap (x and width must be multiple of 4)
LINE, = 4, # Vertical or Horizontal line
TEXT_AREA, = 5, # Area to contain text line(s)
BUTTON, = 6, # Rounded rectangle button with icon and/or text
SWITCH, = 7, # Switch to turn on/off something
PAGE_INDICATOR, = 8, # horizontal bar to indicate navigation across pages
# horizontal bar to indicate progression of something (between 0% and 100%)
PROGRESS_BAR, = 9,
RADIO_BUTTON, = 10, # Indicator to inform whether something is on or off
# Notification bar, to inform user about alarm... only for internal usage
QR_CODE, = 11, # QR Code
KEYBOARD, = 12, # Keyboard
KEYPAD, = 13, # Keypad
SPINNER, = 14, # Spinner
IMAGE_FILE = 15, # Image file (with Ledger compression)
IMAGE, = 2, # Bitmap (x and width must be multiple of 4)
LINE, = 3, # Vertical or Horizontal line
TEXT_AREA, = 4, # Area to contain text line(s)
BUTTON, = 5, # Rounded rectangle button with icon and/or text
SWITCH, = 6, # Switch to turn on/off something
PAGE_INDICATOR, = 7, # horizontal bar to indicate navigation across pages

PROGRESS_BAR, = 8, # horizontal bar to indicate progression of something (between 0% and 100%)
RADIO_BUTTON, = 9, # Indicator to inform whether something is on or off
QR_CODE, = 10, # QR Code
KEYBOARD, = 11, # Keyboard
KEYPAD, = 12, # Keypad
SPINNER, = 13, # Spinner
IMAGE_FILE = 14, # Image file (with Ledger compression)


class NbglAlignment(IntEnum):
Expand All @@ -96,6 +94,9 @@ class NbglFontId(IntEnum):
BAGL_FONT_INTER_SEMIBOLD_24px = 1,
BAGL_FONT_INTER_MEDIUM_32px = 2,
BAGL_FONT_HM_ALPHA_MONO_MEDIUM_32px = 3
BAGL_FONT_INTER_REGULAR_24px_1bpp = 4
BAGL_FONT_INTER_SEMIBOLD_24px_1bpp = 5
BAGL_FONT_INTER_MEDIUM_32px_1bpp = 6


class NbglStyle(IntEnum):
Expand Down Expand Up @@ -183,7 +184,7 @@ class NbglArea(NbglObj):

@classmethod
def from_bytes(cls, data: bytes):
x0, y0, width, height, color_n, bpp_n = struct.unpack('>HHHHBB', data)
x0, y0, width, height, color_n, bpp_n = struct.unpack('>HHHHBB', data[:10])
color = NbglColor(color_n)
bpp = NbglBpp(bpp_n)
return cls(width, height, x0, y0, color, bpp)
Expand All @@ -193,6 +194,18 @@ def size():
return struct.calcsize('>HHHHBB')


@dataclass
class NbglScreen(NbglObj):
area: NbglArea

@classmethod
def from_bytes(cls, data: bytes):
area = NbglArea.from_bytes(data[0:NbglArea.size()])
return cls(
area=area
)


@dataclass
class NbglContainer(NbglObj):
area: NbglArea
Expand Down Expand Up @@ -405,14 +418,25 @@ def from_bytes(cls, data: bytes):
@dataclass
class NbglImage(NbglObj):
area: NbglArea
width: int
height: int
bpp: int
isFile: int
foreground_color: NbglColor

@classmethod
def from_bytes(cls, data):

area = NbglArea.from_bytes(data[0:NbglArea.size()])
foreground_color, = struct.unpack('>B', data[NbglArea.size():])

width,height,bpp,isFile,size, = struct.unpack('>HHBBI', data[NbglArea.size():NbglArea.size()+10])
foreground_color, = struct.unpack('>B', data[NbglArea.size()+10:])
return cls(
area=area,
width=width,
height=height,
bpp=bpp,
isFile=isFile,
foreground_color=NbglColor(foreground_color)
)

Expand Down Expand Up @@ -488,23 +512,28 @@ class NbglKeypad(NbglObj):
border_color: NbglColor
enable_backspace: bool
enable_validate: bool
enable_digits: bool
shuffled:bool

@classmethod
def from_bytes(cls, data: bytes):
area = NbglArea.from_bytes(data[0:NbglArea.size()])
text_color, border_color, enable_backspace, enable_validate = struct.unpack(
'>BBBB', data[NbglArea.size():])
text_color, border_color, enable_backspace, enable_validate, enable_digits, shuffled = \
struct.unpack('>BBBBBB', data[NbglArea.size():NbglArea.size()+6])
return cls(
area=area,
text_color=NbglColor(text_color),
border_color=NbglColor(border_color),
enable_backspace=enable_backspace,
enable_validate=enable_validate
enable_validate=enable_validate,
enable_digits=enable_digits,
shuffled=shuffled
)


# Mapping of NbglObjType and their associated class.
NBGL_OBJ_TYPES = {
NbglObjType.SCREEN: NbglScreen,
NbglObjType.CONTAINER: NbglContainer,
NbglObjType.LINE: NbglLine,
NbglObjType.IMAGE: NbglImage,
Expand Down Expand Up @@ -549,11 +578,13 @@ class NbglDrawObjectEvent(NbglGenericJsonSerializable):

@classmethod
def from_bytes(cls, data: bytes):
obj_type = NbglObjType(data[0])
# the first byte is the object id
# the second one is the object type
obj_type = NbglObjType(data[1])
class_type = NBGL_OBJ_TYPES[obj_type]

return cls(
obj=class_type.from_bytes(data[1:])
obj=class_type.from_bytes(data[2:])
)

def to_json_dict(self) -> Dict:
Expand Down
35 changes: 30 additions & 5 deletions lib_nbgl/serialization/test_bytes_deserialize.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from turtle import back
from nbgl_lib import *
import pytest

Expand All @@ -17,6 +16,26 @@ def run_deserialize_nbgl(hex_str: str):
return deserialize_nbgl_bytes(bytes_in)


def test_draw_nbgl_screen(data_test):
serialized = data_test["test_draw_nbgl_screen"]
deserialized = run_deserialize_nbgl(serialized)
expected = \
NbglDrawObjectEvent(
obj=NbglScreen(
area=NbglArea(
background_color=NbglColor.WHITE,
bpp=NbglBpp.BPP_4,
height=670,
width=400,
x0=0,
y0=0
)
)
)

assert deserialized == expected


def test_draw_nbgl_container(data_test):
serialized = data_test["test_draw_nbgl_container"]
deserialized = run_deserialize_nbgl(serialized)
Expand Down Expand Up @@ -231,12 +250,16 @@ def test_draw_nbgl_image(data_test):
obj=NbglImage(
area=NbglArea(
background_color=NbglColor.WHITE,
bpp=NbglBpp.BPP_2,
height=101,
width=201,
bpp=NbglBpp.BPP_1,
height=32,
width=32,
x0=124,
y0=235
),
height=32,
width=32,
bpp=0,
isFile=1,
foreground_color=NbglColor.DARK_GRAY
)
)
Expand Down Expand Up @@ -285,7 +308,9 @@ def test_draw_nbgl_keypad(data_test):
text_color=NbglColor.WHITE,
border_color=NbglColor.BLACK,
enable_backspace=True,
enable_validate=False
enable_validate=False,
enable_digits=True,
shuffled=False
)
)
assert deserialized == expected
Expand Down
51 changes: 49 additions & 2 deletions lib_nbgl/serialization/test_json_ser_deser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,41 @@
import pytest


def test_json_deserialize_screen():
serialized = {
'event': 'NBGL_DRAW_OBJ',
'obj': {
'type': 'SCREEN',
'content': {
'area': {
'width': 400,
'height': 670,
'x0': 0,
'y0': 0,
'background_color': 'WHITE',
'bpp': 'BPP_4'
}
}
}
}
deserialized = \
NbglDrawObjectEvent(
obj=NbglScreen(
area=NbglArea(
width=400,
height=670,
x0=0,
y0=0,
background_color=NbglColor.WHITE,
bpp=NbglBpp.BPP_4
)
)

)

assert serialize_nbgl_json(deserialized) == serialized
assert deserialized == deserialize_nbgl_json(serialized)

def test_json_deserialize_container():
serialized = {
'event': 'NBGL_DRAW_OBJ',
Expand Down Expand Up @@ -396,6 +431,10 @@ def test_json_deserialize_image():
'background_color': 'BLACK',
'bpp': 'BPP_2'
},
'height':35,
'width':36,
'bpp':2,
'isFile':1,
'foreground_color': 'WHITE'
}
}
Expand All @@ -411,6 +450,10 @@ def test_json_deserialize_image():
background_color=NbglColor.BLACK,
bpp=NbglBpp.BPP_2
),
height=35,
width=36,
bpp=2,
isFile=1,
foreground_color=NbglColor.WHITE
)
)
Expand Down Expand Up @@ -558,7 +601,9 @@ def test_json_deserialize_keypad():
'text_color': 'WHITE',
'border_color': 'LIGHT_GRAY',
'enable_backspace': True,
'enable_validate': False
'enable_validate': False,
'enable_digits': True,
'shuffled': False
}
}
}
Expand All @@ -576,7 +621,9 @@ def test_json_deserialize_keypad():
text_color=NbglColor.WHITE,
border_color=NbglColor.LIGHT_GRAY,
enable_backspace=True,
enable_validate=False
enable_validate=False,
enable_digits=True,
shuffled=False
)
)

Expand Down
3 changes: 3 additions & 0 deletions lib_nbgl/serialization/ux_loc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

typedef unsigned short UX_LOC_STRINGS_INDEX;
4 changes: 2 additions & 2 deletions lib_nbgl/src/nbgl_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include "nbgl_draw.h"
#include "nbgl_front.h"
#include "nbgl_debug.h"
#include "nbgl_serialize.h"
#include "os_print.h"
#include "glyphs.h"
#ifdef HAVE_SERIALIZED_NBGL
#include "nbgl_serialize.h"
#include "os_io_seproxyhal.h"
#endif

Expand All @@ -39,7 +39,7 @@ void extendRefreshArea(nbgl_obj_t *obj);
static nbgl_area_t refreshArea;

// boolean used to enable/forbid drawing/refresh
bool objDrawingDisabled;
static bool objDrawingDisabled;

/**********************
* VARIABLES
Expand Down
15 changes: 15 additions & 0 deletions lib_nbgl/src/nbgl_obj_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,21 @@ nbgl_obj_t *nbgl_objPoolGetPrevious(nbgl_obj_t *obj, uint8_t layer)
return NULL;
}

/**
* @brief Gets a unique index for the given object, in the pool
* @param obj object to get id from
* @return an unique index of the object
*/
uint8_t nbgl_objPoolGetId(nbgl_obj_t *obj)
{
uint8_t index;

// retrieve object index
index = (genericObj_t *) obj - objPool;

return index;
}

/**
* @brief Gets nbObjects new graphic object from the pool, with the given type, for the given layer
* (screen). The type field of the object is set.
Expand Down
Loading

0 comments on commit 562460d

Please sign in to comment.