-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat (libtropic) : Add support for USB dngle
- Loading branch information
1 parent
31d76e8
commit b3b6fb4
Showing
3 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
#include <stdint.h> | ||
#include <stddef.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include <time.h> | ||
#include <fcntl.h> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <termios.h> | ||
|
||
#include "libtropic_common.h" | ||
#include "libtropic_port.h" | ||
|
||
|
||
#define READ_WRITE_DELAY 10 | ||
|
||
int fd; | ||
const char device[] = "/dev/ttyACM0"; | ||
uint32_t baud_rate = 115200; | ||
|
||
// Writes bytes to the serial port, returning 0 on success and -1 on failure. | ||
int write_port(int fd, uint8_t * buffer, size_t size) | ||
{ | ||
ssize_t result = write(fd, buffer, size); | ||
if (result != (ssize_t)size) | ||
{ | ||
perror("failed to write to port"); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
// Reads bytes from the serial port. | ||
// Returns after all the desired bytes have been read, or if there is a | ||
// timeout or other error. | ||
// Returns the number of bytes successfully read into the buffer, or -1 if | ||
// there was an error reading. | ||
ssize_t read_port(int fd, uint8_t * buffer, size_t size) | ||
{ | ||
size_t received = 0; | ||
while (received < size) | ||
{ | ||
ssize_t r = read(fd, buffer + received, size - received); | ||
if (r < 0) | ||
{ | ||
perror("failed to read from port"); | ||
return -1; | ||
} | ||
if (r == 0) | ||
{ | ||
// Timeout | ||
break; | ||
} | ||
received += r; | ||
} | ||
return received; | ||
} | ||
|
||
lt_ret_t lt_port_init(lt_handle_t *h) | ||
{ | ||
UNUSED(h); | ||
memset(h, 0, sizeof(lt_handle_t)); | ||
|
||
// serialport init | ||
fd = open(device, O_RDWR | O_NOCTTY); | ||
if (fd == -1) | ||
{ | ||
perror(device); | ||
return LT_FAIL; | ||
} | ||
|
||
// Flush away any bytes previously read or written. | ||
int result = tcflush(fd, TCIOFLUSH); | ||
if (result) | ||
{ | ||
perror("tcflush failed"); // just a warning, not a fatal error | ||
} | ||
|
||
// Get the current configuration of the serial port. | ||
struct termios options; | ||
result = tcgetattr(fd, &options); | ||
if (result) | ||
{ | ||
perror("tcgetattr failed"); | ||
close(fd); | ||
return LT_FAIL; | ||
} | ||
|
||
// Turn off any options that might interfere with our ability to send and | ||
// receive raw binary bytes. | ||
options.c_iflag &= ~(INLCR | IGNCR | ICRNL | IXON | IXOFF); | ||
options.c_oflag &= ~(ONLCR | OCRNL); | ||
options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); | ||
|
||
// Set up timeouts: Calls to read() will return as soon as there is | ||
// at least one byte available or when 100 ms has passed. | ||
options.c_cc[VTIME] = 1; | ||
options.c_cc[VMIN] = 0; | ||
|
||
// This code only supports certain standard baud rates. Supporting | ||
// non-standard baud rates should be possible but takes more work. | ||
switch (baud_rate) | ||
{ | ||
case 4800: cfsetospeed(&options, B4800); break; | ||
case 9600: cfsetospeed(&options, B9600); break; | ||
case 19200: cfsetospeed(&options, B19200); break; | ||
case 38400: cfsetospeed(&options, B38400); break; | ||
case 115200: cfsetospeed(&options, B115200); break; | ||
default: | ||
fprintf(stderr, "warning: baud rate %u is not supported, using 9600.\n", | ||
baud_rate); | ||
cfsetospeed(&options, B9600); | ||
break; | ||
} | ||
cfsetispeed(&options, cfgetospeed(&options)); | ||
|
||
result = tcsetattr(fd, TCSANOW, &options); | ||
if (result) | ||
{ | ||
perror("tcsetattr failed"); | ||
close(fd); | ||
return LT_FAIL; | ||
} | ||
|
||
return LT_OK; | ||
} | ||
|
||
lt_ret_t lt_port_deinit(lt_handle_t *h) | ||
{ | ||
UNUSED(h); | ||
close(fd); | ||
|
||
return LT_OK; | ||
} | ||
|
||
lt_ret_t lt_port_delay (lt_handle_t *h, uint32_t wait_time_msecs) | ||
{ | ||
UNUSED(h); | ||
usleep(wait_time_msecs*1000); | ||
return LT_OK; | ||
} | ||
|
||
lt_ret_t lt_port_random_bytes(uint32_t *buff, uint16_t len) { | ||
|
||
for(int i=0; i<len; i++) { | ||
buff[i] = (uint32_t)rand(); | ||
} | ||
|
||
return LT_OK; | ||
} | ||
|
||
|
||
lt_ret_t lt_port_spi_csn_low (lt_handle_t *h) | ||
{ | ||
UNUSED(h); | ||
/* CS LOW is handled automatically when SPI transfer is executed */ | ||
return LT_OK; | ||
} | ||
|
||
lt_ret_t lt_port_spi_csn_high (lt_handle_t *h) | ||
{ | ||
UNUSED(h); | ||
|
||
char cs_high[] = "CS=0\n"; // Yes, CS=0 really means that CSN is low | ||
if(write_port(fd, cs_high, 5) != 0) { | ||
return LT_L1_SPI_ERROR; | ||
} | ||
|
||
uint8_t buff[4]; | ||
int readed = read_port(fd, buff, 4); | ||
if(readed != 4) { | ||
return LT_L1_SPI_ERROR; | ||
} | ||
|
||
if(memcmp(buff, "OK\r\n", 4) !=0) { | ||
return LT_L1_SPI_ERROR; | ||
} | ||
return LT_OK; | ||
} | ||
|
||
lt_ret_t lt_port_spi_transfer (lt_handle_t *h, uint8_t offset, uint16_t tx_data_length, uint32_t timeout) | ||
{ | ||
UNUSED(h); | ||
UNUSED(timeout); | ||
|
||
if (offset + tx_data_length > LT_L1_LEN_MAX) { | ||
return LT_L1_DATA_LEN_ERROR; | ||
} | ||
|
||
// Bytes from handle which are about to be sent are encoded as chars and stored here: | ||
char buffered_chars[512] = {0}; | ||
for(int i=0; i<(tx_data_length); i++) { | ||
sprintf(buffered_chars + i*2, "%02X", h->l2_buff[i+offset]); // TODO make this better? | ||
} | ||
// Controll characters to keep CS LOW, they are expected by USB dongle | ||
buffered_chars[tx_data_length*2] = 'x'; | ||
buffered_chars[tx_data_length*2+1] = '\n'; | ||
|
||
|
||
int ret = write_port(fd, buffered_chars, (tx_data_length*2)+2); | ||
if(ret != 0) { | ||
return LT_L1_SPI_ERROR; | ||
} | ||
|
||
lt_port_delay(h, READ_WRITE_DELAY); | ||
|
||
int readed = read_port(fd, buffered_chars, (2*tx_data_length)+2); | ||
if(readed!= ((2*tx_data_length)+2)) { | ||
return LT_L1_SPI_ERROR; | ||
} | ||
|
||
for (size_t count = 0; count < 2*tx_data_length; count++) { | ||
sscanf(&buffered_chars[count*2], "%2hhx", &h->l2_buff[count+offset]); // TODO make this better? | ||
} | ||
|
||
return LT_OK; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
cmake_minimum_required(VERSION 3.21.0) | ||
|
||
|
||
########################################################################### | ||
# # | ||
# Paths and setup # | ||
# # | ||
########################################################################### | ||
|
||
#set(CMAKE_BUILD_TYPE Debug) | ||
|
||
set(PATH_TREZOR_CRYPTO "../../vendor/trezor_crypto/") | ||
set(PATH_LIBTROPIC "../../../") | ||
|
||
|
||
########################################################################### | ||
# # | ||
# Define project's name # | ||
# # | ||
########################################################################### | ||
|
||
project(libtropic_unix_example | ||
VERSION 0.1.0 | ||
DESCRIPTION "Example of libtropic's usage in Unix environment" | ||
LANGUAGES C) | ||
|
||
|
||
########################################################################### | ||
# # | ||
# Sources defined by this project # | ||
# # | ||
########################################################################### | ||
|
||
add_executable(run main.c | ||
${CMAKE_CURRENT_SOURCE_DIR}/${PATH_LIBTROPIC}hal/port/unix/lt_port_unix_usb_dongle.c | ||
) | ||
|
||
|
||
########################################################################### | ||
# # | ||
# Define what examples will be compiled into main(). # | ||
# If any of examples is enabled, libtropic is compiled with # | ||
# examples exposed. # | ||
# # | ||
########################################################################### | ||
|
||
# -DLT_EX_HW_WALLET=1 | ||
if(LT_EX_HW_WALLET) | ||
set(LT_ADD_EXAMPLES ON) | ||
target_compile_definitions(run PRIVATE LT_EX_HW_WALLET) | ||
endif() | ||
# -DLT_EX_HELLO_WORLD=1 | ||
if(LT_EX_HELLO_WORLD) | ||
set(LT_ADD_EXAMPLES ON) | ||
target_compile_definitions(run PRIVATE LT_EX_HELLO_WORLD) | ||
endif() | ||
# -DLT_EX_TEST_REVERSIBLE=1 | ||
if(LT_EX_TEST_REVERSIBLE) | ||
set(LT_ADD_EXAMPLES ON) | ||
target_compile_definitions(run PRIVATE LT_EX_TEST_REVERSIBLE) | ||
endif() | ||
# --DLT_EX_TEST_IREVERSIBLE=1 | ||
if(LT_EX_TEST_IREVERSIBLE) | ||
set(LT_ADD_EXAMPLES ON) | ||
target_compile_definitions(run PRIVATE LT_EX_TEST_IREVERSIBLE) | ||
endif() | ||
|
||
########################################################################### | ||
# # | ||
# Add libtropic and set it up # | ||
# # | ||
########################################################################### | ||
|
||
# Use trezor crypto as a source of backend cryptography code | ||
set(LT_USE_TREZOR_CRYPTO ON) | ||
|
||
# Add path to libtropic's repository root folder | ||
add_subdirectory(${PATH_LIBTROPIC} "libtropic") | ||
|
||
# Customize libtropic's compilation | ||
target_compile_options(tropic PRIVATE -Wall) | ||
target_compile_options(tropic PRIVATE -ffunction-sections -fdata-sections) | ||
target_compile_options(tropic PRIVATE -Wno-implicit-function-declaration) | ||
|
||
|
||
########################################################################### | ||
# # | ||
# Link executable # | ||
# # | ||
########################################################################### | ||
|
||
target_link_options(run PRIVATE -Wl,--gc-sections) | ||
target_link_libraries(run PRIVATE tropic) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/** | ||
* @file main.c | ||
* @author Tropic Square s.r.o. | ||
* | ||
* @license For the license see file LICENSE.txt file in the root directory of this source tree. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include "string.h" | ||
#include "libtropic_examples.h" | ||
|
||
int main(void) | ||
{ | ||
// Test routines | ||
#ifdef LT_EX_TEST_REVERSIBLE | ||
lt_ex_test_reversible(); | ||
#endif | ||
#ifdef LT_EX_TEST_IREVERSIBLE | ||
lt_ex_test_ireversible(); | ||
#endif | ||
|
||
// Full examples | ||
#ifdef LT_FEATURES_FWUPDATE | ||
lt_ex_fwupdate(); | ||
#endif | ||
#ifdef LT_EX_HELLO_WORLD | ||
/*int*/ lt_ex_hello_world(); | ||
#endif | ||
#ifdef LT_EX_HW_WALLET | ||
/*int*/ lt_ex_hardware_wallet(); | ||
#endif | ||
|
||
} |