Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sign&&rotate #3

Merged
merged 1 commit into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
source "Kconfig.zephyr"

config PW_SIGN_KEY
string "Signing key"

config PW_ROTATE_PERIOD_SEC
int "How ofen message will be rotated"
default 15

config ADV_BTN_TIMES
int "How many times button press must be notified"
default 10
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: all build push
.PHONY: all build debug push

BOARD := "xiao_ble"

Expand All @@ -7,5 +7,8 @@ all: push
build:
west build -p always -b ${BOARD} .

debug:
west debug -r blackmagicprobe

push: build
west -v flash -r blackmagicprobe
3 changes: 3 additions & 0 deletions boards/xiao_ble.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_LOG=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
9 changes: 8 additions & 1 deletion prj.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
CONFIG_BT_DEVICE_NAME="PinkyWinky"
CONFIG_PW_SIGN_KEY="lol-kek-cheburek"

CONFIG_MAIN_STACK_SIZE=2048

CONFIG_LOG=n
Expand All @@ -7,10 +10,14 @@ CONFIG_CONSOLE=n
CONFIG_BT=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_PER_ADV=n
CONFIG_BT_DEVICE_NAME="PinkyWinky"
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=64

CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_HEAP_SIZE=512
CONFIG_MBEDTLS_SHA1=y

CONFIG_PM_DEVICE=y

CONFIG_PINCTRL=y
Expand Down
3 changes: 2 additions & 1 deletion pw-linux.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"variant": "c",
"charconv": "c",
"format": "c",
"cstdint": "c"
"cstdint": "c",
"stdbool.h": "c"
},
"zephyr-ide.projects": {},
"python.defaultInterpreterPath": "~/zephyr/.venv/bin/python",
Expand Down
76 changes: 65 additions & 11 deletions src/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <zephyr/sys/byteorder.h>
#include <zephyr/logging/log.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <mbedtls/sha1.h>

#include "btn.h"

Expand All @@ -19,7 +20,8 @@ LOG_MODULE_REGISTER(pw_ble);
#define IDX_MFG_BATT_LVL 3
#define IDX_MFG_BTN_STATE (IDX_MFG_BATT_LVL + 1)
#define IDX_MFG_TS (IDX_MFG_BTN_STATE + 1)
#define IDX_MFG_SIGN (IDX_MFG_TS + 8)
#define IDX_MFG_SIGN (IDX_MFG_TS + 4)
#define MFG_SIGN_LEN (10)

static uint8_t mfg_data[] = {
/* company ID must be 0xffff by spec */
Expand All @@ -31,9 +33,9 @@ static uint8_t mfg_data[] = {
/* button state */
0x00,
/* ts */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* md5 sign */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00,
/* truncated to 10 bytes sha1 sign */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

static const struct bt_data advertising[] = {
Expand All @@ -43,14 +45,57 @@ static const struct bt_data advertising[] = {
};

static struct bt_le_ext_adv *adv = NULL;
static uint64_t initial_ts = 0;
static uint32_t pw_initial_ts = 0;
static uint32_t pw_last_ts = 0;

static uint8_t mfg_hash_buf[20] = {};
static mbedtls_sha1_context mfg_hash_ctx;

int pw_ble_update_mfg_sign()
{
int err;

err = mbedtls_sha1_starts(&mfg_hash_ctx);
if (err) {
LOG_ERR("failed to start sha1 hash (err %d)", err);
return -1;
}

err = mbedtls_sha1_update(&mfg_hash_ctx, &mfg_data[0], IDX_MFG_SIGN);
if (err) {
LOG_ERR("failed to update hash (err %d)", err);
return -1;
}

err = mbedtls_sha1_update(&mfg_hash_ctx, CONFIG_PW_SIGN_KEY, sizeof(CONFIG_PW_SIGN_KEY) - 1);
if (err) {
LOG_ERR("failed to update hash (err %d)", err);
return -1;
}

err = mbedtls_sha1_finish(&mfg_hash_ctx, mfg_hash_buf);
if (err) {
LOG_ERR("failed to calculate hash (err %d)", err);
return -1;
}

memcpy(&mfg_data[IDX_MFG_SIGN], mfg_hash_buf, MFG_SIGN_LEN);
return 0;
}

void pw_ble_update_adv_data()
{
int err;

mfg_data[IDX_MFG_BTN_STATE] = pw_btn_is_pressed() ? 1 : 0;
sys_put_be64(initial_ts, &mfg_data[IDX_MFG_TS]);
pw_last_ts = pw_initial_ts + k_uptime_seconds();
LOG_INF("upd: %u", pw_last_ts);
mfg_data[IDX_MFG_BTN_STATE] = is_pw_btn_pressed() ? 1 : 0;
sys_put_be32(pw_last_ts, &mfg_data[IDX_MFG_TS]);

err = pw_ble_update_mfg_sign();
if (err) {
LOG_ERR("failed to sign mfg data (err %d)", err);
}

err = bt_le_ext_adv_set_data(adv, advertising, ARRAY_SIZE(advertising), NULL, 0);
if (err) {
Expand All @@ -65,12 +110,11 @@ void pw_ble_refresh_adv_data(struct k_work *work)

K_WORK_DEFINE(refresh_adv_data_work, pw_ble_refresh_adv_data);


int pw_ble_init_adv_data()
{
int err;

err = bt_rand(&initial_ts, sizeof(uint32_t));
err = bt_rand(&pw_initial_ts, sizeof(uint16_t));
if (err) {
LOG_ERR("couldn't generate initial ts (err %d)", err);
return -1;
Expand All @@ -80,12 +124,20 @@ int pw_ble_init_adv_data()
return 0;
}

void pw_ble_adv_timer_cb(struct k_timer *dummy)
{
LOG_INF("rotate data");
pw_ble_refresh_data();
}

K_TIMER_DEFINE(pw_ble_adv_timer, pw_ble_adv_timer_cb, NULL);

int pw_ble_enable()
{
int err;

/* Initialize the Bluetooth Subsystem */
mbedtls_sha1_init(&mfg_hash_ctx);

err = bt_enable(NULL);
if (err) {
LOG_ERR("bluetooth init failed (err %d)", err);
Expand All @@ -107,7 +159,6 @@ int pw_ble_enable()
return -1;
}

/* Set advertising data */
err = pw_ble_init_adv_data();
if (err) {
LOG_ERR("advertising init failed (err %d)", err);
Expand All @@ -120,6 +171,9 @@ int pw_ble_enable()
LOG_ERR("failed to start extended advertising (err %d)", err);
return -1;
}

LOG_INF("start adv msg rotation...");
k_timer_start(&pw_ble_adv_timer, K_SECONDS(CONFIG_PW_ROTATE_PERIOD_SEC), K_SECONDS(CONFIG_PW_ROTATE_PERIOD_SEC));

LOG_INF("BLE initialized");
return 0;
Expand Down
10 changes: 5 additions & 5 deletions src/btn.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(pw_btn);
static const struct gpio_dt_spec pw_btn = GPIO_DT_SPEC_GET(SW_NODE, gpios);
static struct gpio_callback pw_btn_cb_data;

static uint8_t pw_btn_pressed = 0;
static bool pw_btn_pressed = 0;
static uint32_t pw_btn_last_time = 0;

void pw_btn_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins);
Expand Down Expand Up @@ -53,13 +53,13 @@ int pw_btn_enable()
return 0;
}

int pw_btn_is_pressed() {
return pw_btn_pressed ? 1 : 0;
bool is_pw_btn_pressed() {
return pw_btn_pressed;
}

void pw_btn_release_cb(struct k_timer *dummy)
{
pw_btn_pressed = 0;
pw_btn_pressed = false;
pw_led_off();
pw_ble_refresh_data();
}
Expand All @@ -76,7 +76,7 @@ void pw_btn_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins

LOG_INF("button pressed at %" PRIu64, k_uptime_get());
pw_btn_last_time = time;
pw_btn_pressed = 1;
pw_btn_pressed = true;
pw_led_on();
pw_ble_refresh_data();
k_timer_start(&pw_btn_release_timer, K_MSEC(CONFIG_ADV_BTN_TIMES * CONFIG_ADV_INTERVAL_MAX_MS), K_NO_WAIT);
Expand Down
4 changes: 3 additions & 1 deletion src/btn.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#ifndef H_PW_BTN_
#define H_PW_BTN_

#include <stdbool.h>

int pw_btn_enable();
int pw_btn_is_pressed();
bool is_pw_btn_pressed();

#endif