mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[ion] Encode the serial number in Base64
Also, expose serialNumber() in Ion and keep "copySerialNumber" in Ion::Device. This allows the DFU bootloader to remain .bss-free.
This commit is contained in:
@@ -10,9 +10,7 @@ SerialNumberController::SerialNumberController(Responder * parentResponder) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SerialNumberController::viewWillAppear() {
|
void SerialNumberController::viewWillAppear() {
|
||||||
static char serialNumber[24];
|
m_barCodeView.setData(Ion::serialNumber());
|
||||||
Ion::getSerialNumber(serialNumber);
|
|
||||||
m_barCodeView.setData(serialNumber);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SerialNumberController::handleEvent(Ion::Events::Event event) {
|
bool SerialNumberController::handleEvent(Ion::Events::Event event) {
|
||||||
|
|||||||
@@ -192,24 +192,13 @@ void SubController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
|||||||
}
|
}
|
||||||
if (m_messageTreeModel->label() == I18n::Message::About) {
|
if (m_messageTreeModel->label() == I18n::Message::About) {
|
||||||
myCell->setMessageFontSize(KDText::FontSize::Small);
|
myCell->setMessageFontSize(KDText::FontSize::Small);
|
||||||
const char * accessoryMessage = nullptr;
|
const char * messages[] = {
|
||||||
char serialNumber[Ion::SerialNumberLength+1];
|
Ion::softwareVersion(),
|
||||||
switch (index) {
|
Ion::serialNumber(),
|
||||||
case 0:
|
Ion::fccId()
|
||||||
accessoryMessage = Ion::softwareVersion();
|
};
|
||||||
break;
|
assert(index >= 0 && index < 3);
|
||||||
case 1:
|
myCell->setAccessoryText(messages[index]);
|
||||||
Ion::getSerialNumber(serialNumber);
|
|
||||||
accessoryMessage = serialNumber;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
accessoryMessage = Ion::fccId();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
myCell->setAccessoryText(accessoryMessage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ namespace Ion {
|
|||||||
void msleep(long ms);
|
void msleep(long ms);
|
||||||
void usleep(long us);
|
void usleep(long us);
|
||||||
|
|
||||||
constexpr static int SerialNumberLength = 24;
|
const char * serialNumber();
|
||||||
void getSerialNumber(char * buffer);
|
|
||||||
const char * softwareVersion();
|
const char * softwareVersion();
|
||||||
const char * patchLevel();
|
const char * patchLevel();
|
||||||
const char * fccId();
|
const char * fccId();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ objs += $(addprefix ion/src/shared/, \
|
|||||||
objs += $(addprefix ion/src/device/, \
|
objs += $(addprefix ion/src/device/, \
|
||||||
backlight.o \
|
backlight.o \
|
||||||
battery.o\
|
battery.o\
|
||||||
|
base64.o\
|
||||||
console.o \
|
console.o \
|
||||||
device.o\
|
device.o\
|
||||||
display.o\
|
display.o\
|
||||||
|
|||||||
48
ion/src/device/base64.cpp
Normal file
48
ion/src/device/base64.cpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
namespace Base64 {
|
||||||
|
|
||||||
|
static constexpr char encodeTable[] = {
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||||
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||||
|
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||||
|
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
|
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||||
|
'4', '5', '6', '7', '8', '9', '+', '/',
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr char Padding = '=';
|
||||||
|
|
||||||
|
void encode(const unsigned char * input, unsigned int inputLength, char * output) {
|
||||||
|
unsigned int i, j;
|
||||||
|
for (i = j = 0; i < inputLength; i++) {
|
||||||
|
int s = i % 3; /* from 6/gcd(6, 8) */
|
||||||
|
|
||||||
|
switch (s) {
|
||||||
|
case 0:
|
||||||
|
output[j++] = encodeTable[(input[i] >> 2) & 0x3F];
|
||||||
|
continue;
|
||||||
|
case 1:
|
||||||
|
output[j++] = encodeTable[((input[i-1] & 0x3) << 4) + ((input[i] >> 4) & 0xF)];
|
||||||
|
continue;
|
||||||
|
case 2:
|
||||||
|
output[j++] = encodeTable[((input[i-1] & 0xF) << 2) + ((input[i] >> 6) & 0x3)];
|
||||||
|
output[j++] = encodeTable[input[i] & 0x3F];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move back */
|
||||||
|
i -= 1;
|
||||||
|
|
||||||
|
/* check the last and add padding */
|
||||||
|
if ((i % 3) == 0) {
|
||||||
|
output[j++] = encodeTable[(input[i] & 0x3) << 4];
|
||||||
|
output[j++] = Padding;
|
||||||
|
output[j++] = Padding;
|
||||||
|
} else if ((i % 3) == 1) {
|
||||||
|
output[j++] = encodeTable[(input[i] & 0xF) << 2];
|
||||||
|
output[j++] = Padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
5
ion/src/device/base64.h
Normal file
5
ion/src/device/base64.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
namespace Base64 {
|
||||||
|
|
||||||
|
void encode(const unsigned char * input, unsigned int inputLength, char * output);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include <ion.h>
|
#include <ion.h>
|
||||||
|
#include "../../device.h"
|
||||||
|
|
||||||
namespace Ion {
|
namespace Ion {
|
||||||
namespace Device {
|
namespace Device {
|
||||||
@@ -11,8 +12,8 @@ void MCUSerial(const char * input) {
|
|||||||
reply(sSyntaxError);
|
reply(sSyntaxError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char response[11+Ion::SerialNumberLength + 1] = {'M', 'C', 'U', '_', 'S', 'E', 'R', 'I', 'A', 'L', '=', 0};
|
char response[11 + Ion::Device::SerialNumberLength + 1] = {'M', 'C', 'U', '_', 'S', 'E', 'R', 'I', 'A', 'L', '=', 0};
|
||||||
Ion::getSerialNumber(response+11);
|
Ion::Device::copySerialNumber(response + 11);
|
||||||
reply(response);
|
reply(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ extern "C" {
|
|||||||
#include "swd.h"
|
#include "swd.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "bench/bench.h"
|
#include "bench/bench.h"
|
||||||
|
#include "base64.h"
|
||||||
|
|
||||||
#define USE_SD_CARD 0
|
#define USE_SD_CARD 0
|
||||||
|
|
||||||
@@ -65,23 +66,18 @@ uint32_t Ion::random() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ion::Device::copySerialNumber(char * buffer) {
|
||||||
|
const unsigned char * rawUniqueID = (const unsigned char *)0x1FFF7A10;
|
||||||
static inline char hex(uint8_t d) {
|
Base64::encode(rawUniqueID, 12, buffer);
|
||||||
if (d > 9) {
|
buffer[SerialNumberLength] = 0;
|
||||||
return 'A'+d-10;
|
|
||||||
}
|
|
||||||
return '0'+d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ion::getSerialNumber(char * buffer) {
|
const char * Ion::serialNumber() {
|
||||||
uint8_t * rawUniqueID = (uint8_t *)0x1FFF7A10;
|
static char serialNumber[Device::SerialNumberLength + 1] = {0};
|
||||||
for (int i=0; i<SerialNumberLength/2; i++) {
|
if (serialNumber[0] == 0) {
|
||||||
uint8_t d = *rawUniqueID++;
|
Device::copySerialNumber(serialNumber);
|
||||||
buffer[2*i] = hex(d >> 4);
|
|
||||||
buffer[2*i+1] = hex(d & 0xF);
|
|
||||||
}
|
}
|
||||||
buffer[SerialNumberLength] = 0;
|
return serialNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private Ion::Device methods
|
// Private Ion::Device methods
|
||||||
|
|||||||
@@ -16,6 +16,14 @@ void shutdownPeripherals();
|
|||||||
void initClocks();
|
void initClocks();
|
||||||
void shutdownClocks();
|
void shutdownClocks();
|
||||||
|
|
||||||
|
/* The serial number is 96 bits long. That's equal to 16 digits in base 64. We
|
||||||
|
* expose a convenient "copySerialNumber" routine which can be called without
|
||||||
|
* using a static variable (and therefore without a .bss section). This is used
|
||||||
|
* in the RAM'ed DFU bootloader. */
|
||||||
|
constexpr static int SerialNumberLength = 16;
|
||||||
|
void copySerialNumber(char * buffer);
|
||||||
|
|
||||||
|
|
||||||
/* Pin | Role | Mode | Function
|
/* Pin | Role | Mode | Function
|
||||||
* -----+-------------------+-----------------------+----------
|
* -----+-------------------+-----------------------+----------
|
||||||
* PA0 | Battery sensing | |
|
* PA0 | Battery sensing | |
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ dfu_objs += ion/src/device/usb/boot.o
|
|||||||
dfu_objs += ion/src/device/keyboard.o
|
dfu_objs += ion/src/device/keyboard.o
|
||||||
dfu_objs += ion/src/device/device.o
|
dfu_objs += ion/src/device/device.o
|
||||||
dfu_objs += ion/src/device/usb.o
|
dfu_objs += ion/src/device/usb.o
|
||||||
|
dfu_objs += ion/src/device/base64.o
|
||||||
|
|
||||||
ion/src/device/usb/dfu.elf: LDFLAGS = --gc-sections -T ion/src/device/usb/dfu.ld
|
ion/src/device/usb/dfu.elf: LDFLAGS = --gc-sections -T ion/src/device/usb/dfu.ld
|
||||||
ion/src/device/usb/dfu.elf: $(usb_objs) $(dfu_objs)
|
ion/src/device/usb/dfu.elf: $(usb_objs) $(dfu_objs)
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ namespace USB {
|
|||||||
namespace Device {
|
namespace Device {
|
||||||
|
|
||||||
void Calculator::PollAndReset(bool exitWithKeyboard) {
|
void Calculator::PollAndReset(bool exitWithKeyboard) {
|
||||||
char serialNumber[Ion::SerialNumberLength+1];
|
char serialNumber[Ion::Device::SerialNumberLength+1];
|
||||||
Ion::getSerialNumber(serialNumber);
|
Ion::Device::copySerialNumber(serialNumber);
|
||||||
Calculator c(serialNumber);
|
Calculator c(serialNumber);
|
||||||
|
|
||||||
/* Leave DFU mode if the Back key is pressed, the calculator unplugged or the
|
/* Leave DFU mode if the Back key is pressed, the calculator unplugged or the
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <ion.h>
|
#include <ion.h>
|
||||||
|
|
||||||
void Ion::getSerialNumber(char * buffer) {
|
const char * Ion::serialNumber() {
|
||||||
strlcpy(buffer, "000000000000000000000000", Ion::SerialNumberLength+1);
|
return "000000000000";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ objs += $(addprefix ion/src/shared/, \
|
|||||||
dummy/backlight.o \
|
dummy/backlight.o \
|
||||||
dummy/battery.o \
|
dummy/battery.o \
|
||||||
dummy/fcc_id.o \
|
dummy/fcc_id.o \
|
||||||
|
dummy/serial_number.o \
|
||||||
dummy/usb.o \
|
dummy/usb.o \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,3 @@ void Ion::msleep(long ms) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ion::getSerialNumber(char * buffer) {
|
|
||||||
strlcpy(buffer, "Simulator", Ion::SerialNumberLength+1);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user