allow overrides to be used in stat display
This commit is contained in:
@@ -40,6 +40,7 @@ add_executable(BattMITM_2.0
|
||||
smbus.c
|
||||
static_queue.c
|
||||
mitm.c
|
||||
override.c
|
||||
status.c
|
||||
display.c
|
||||
font.c
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "battery.h"
|
||||
#include "config.h"
|
||||
#include "smbus.h"
|
||||
#include "mitm.h"
|
||||
#include "override.h"
|
||||
#include "hardware/sync.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include <stdlib.h>
|
||||
@@ -74,6 +76,57 @@ void battery_stat_request_update(battery_stat_t* batt_stat) {
|
||||
}
|
||||
|
||||
|
||||
void battery_update_stat(battery_stat_t* batt_stat) {
|
||||
i2c_dev_t* bms = get_bms_dev();
|
||||
cmd_reply_override override = NULL;
|
||||
int ret;
|
||||
|
||||
printf("updating %02x (%s)\n", batt_stat->read_command, batt_stat->friendly_name);
|
||||
|
||||
if (defused_use_read_command_reply_override(batt_stat->read_command)) {
|
||||
override = get_read_command_reply_override(batt_stat->read_command);
|
||||
if (override != NULL) printf("using read cmd override\n");
|
||||
}
|
||||
|
||||
switch (batt_stat->type) {
|
||||
case SBS_BYTES:
|
||||
if (override != NULL) {
|
||||
ret = mitm_smbus_read_with_override(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length, false, override);
|
||||
} else {
|
||||
ret = smbus_read(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length);
|
||||
}
|
||||
break;
|
||||
case SBS_BLOCK:
|
||||
if (override != NULL) {
|
||||
ret = mitm_smbus_read_with_override(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length, true, override);
|
||||
} else {
|
||||
ret = smbus_read_block(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length);
|
||||
}
|
||||
break;
|
||||
case SBS_STRING:
|
||||
if (override != NULL) {
|
||||
// ret = mitm_smbus_read_text_with_override(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length, override);
|
||||
ret = mitm_smbus_read_with_override(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length, true, override);
|
||||
} else {
|
||||
ret = smbus_read_text(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
batt_stat->result_valid = false;
|
||||
} else {
|
||||
batt_stat->result_valid = true;
|
||||
batt_stat->result_length = ret;
|
||||
batt_stat->update_requested = false;
|
||||
}
|
||||
|
||||
batt_stat->last_updated = time_us_64();
|
||||
}
|
||||
|
||||
|
||||
void battery_update_cache() {
|
||||
if (!battery_stat_need_cache_update) return;
|
||||
|
||||
@@ -81,40 +134,14 @@ void battery_update_cache() {
|
||||
|
||||
battery_stat_need_cache_update = false;
|
||||
|
||||
i2c_dev_t* bms = get_bms_dev();
|
||||
battery_stat_t* batt_stat;
|
||||
int ret;
|
||||
|
||||
for (int i = 0; i < battery_stat_cache_size; i++) {
|
||||
batt_stat = &battery_stat_cache[i];
|
||||
if (!batt_stat->update_requested) continue;
|
||||
if (batt_stat->last_updated + BATTERY_STAT_MIN_RETRY_PERIOD > time_us_64()) continue;
|
||||
|
||||
printf("update requested for %02x (%s)\n", batt_stat->read_command, batt_stat->friendly_name);
|
||||
|
||||
switch (batt_stat->type) {
|
||||
case SBS_BYTES:
|
||||
ret = smbus_read(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length);
|
||||
break;
|
||||
case SBS_BLOCK:
|
||||
ret = smbus_read_block(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length);
|
||||
break;
|
||||
case SBS_STRING:
|
||||
ret = smbus_read_text(bms, batt_stat->read_command, batt_stat->cached_result.as_uint8, batt_stat->max_result_length);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
batt_stat->result_valid = false;
|
||||
} else {
|
||||
batt_stat->result_valid = true;
|
||||
batt_stat->result_length = ret;
|
||||
batt_stat->update_requested = false;
|
||||
}
|
||||
|
||||
batt_stat->last_updated = time_us_64();
|
||||
battery_update_stat(batt_stat);
|
||||
}
|
||||
|
||||
battery_stat_unlock();
|
||||
@@ -180,7 +207,7 @@ void init_battery() {
|
||||
create_battery_stat(BATT_CMD_MANUFACTURER_NAME, "manufacturer", 32, SBS_STRING, BATTERY_STAT_VALID_PERIOD_CONSTANT),
|
||||
create_battery_stat(BATT_CMD_DEVICE_NAME, "device name", 32, SBS_STRING, BATTERY_STAT_VALID_PERIOD_CONSTANT),
|
||||
create_battery_stat(BATT_CMD_DEVICE_CHEMISTRY, "chemistry", 16, SBS_STRING, BATTERY_STAT_VALID_PERIOD_CONSTANT),
|
||||
create_battery_stat(BATT_CMD_MANUFACTURER_DATA, "manufacturer data", 14, SBS_BLOCK, BATTERY_STAT_VALID_PERIOD_CONSTANT),
|
||||
create_battery_stat(BATT_CMD_MANUFACTURER_DATA, "manufacturer data", 14, SBS_BLOCK, BATTERY_STAT_VALID_PERIOD_DEFAULT),
|
||||
};
|
||||
battery_stat_cache_size = sizeof(battery_stat_cache_init) / sizeof(battery_stat_t);
|
||||
battery_stat_cache = malloc(sizeof(battery_stat_cache_init));
|
||||
|
||||
+14
-1
@@ -159,7 +159,7 @@ int override_example_modify_manufacturer_name(uint8_t cmd, uint8_t* reply_buffer
|
||||
|
||||
// map command codes to override functions here
|
||||
// for a list of command code definitions see battery.h
|
||||
cmd_reply_override get_read_command_reply_override(uint8_t cmd) {
|
||||
cmd_reply_override config_get_read_command_reply_override(uint8_t cmd) {
|
||||
switch (cmd) {
|
||||
|
||||
// examples:
|
||||
@@ -172,6 +172,19 @@ cmd_reply_override get_read_command_reply_override(uint8_t cmd) {
|
||||
}
|
||||
|
||||
|
||||
// defines whether the gui (defused) will use the override instead of reading directly from the battery
|
||||
bool config_defused_use_read_command_reply_override(uint8_t cmd) {
|
||||
// you can write a switch statement here to change this behavior per command
|
||||
return true; // use the override by default
|
||||
}
|
||||
|
||||
|
||||
// defines whether the uart interface (not yet implemented) will use the override instead of reading directly from the battery
|
||||
bool config_uart_use_read_command_reply_override(uint8_t cmd) {
|
||||
// you can write a switch statement here to change this behavior per command
|
||||
return false; // don't use the override by default
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/irq.h"
|
||||
#include <stdio.h>
|
||||
#include "config_override.h"
|
||||
#include "override.h"
|
||||
|
||||
enum i2c_transfer_event {
|
||||
I2C_READ,
|
||||
@@ -339,3 +339,67 @@ void mitm_loop() {
|
||||
|
||||
}
|
||||
|
||||
int mitm_smbus_read_with_override(i2c_dev_t* device, uint8_t cmd, uint8_t* result, size_t length, bool is_block, cmd_reply_override override) {
|
||||
int ret;
|
||||
uint8_t block_length;
|
||||
|
||||
if (length > MITM_REPLY_BUFFER_SIZE - 1) return -1;
|
||||
|
||||
printf("reading cmd 0x%02x with override\n", cmd);
|
||||
|
||||
// set up for read cmd
|
||||
mitm_cmd_buffer[0] = cmd;
|
||||
mitm_cmd_buffer_index = 1;
|
||||
|
||||
ret = i2c_write_timeout_us(device->i2c, device->address, mitm_cmd_buffer, mitm_cmd_buffer_index, true, device->timeout);
|
||||
if (ret < 0) {
|
||||
printf("failed, write returned %d\n", ret);
|
||||
return SMBUS_ERROR_DEVICE;
|
||||
}
|
||||
|
||||
|
||||
ret = override(cmd, mitm_reply_buffer);
|
||||
i2c_stop_read_blocking(device);
|
||||
if (ret < 0) {
|
||||
printf("failed, override returned %d\n", ret);
|
||||
return SMBUS_ERROR_CRC; // pretend it was corrupted
|
||||
}
|
||||
|
||||
// read the result from the buffer like the laptop would
|
||||
|
||||
if (is_block) {
|
||||
block_length = mitm_reply_buffer[0];
|
||||
if (block_length > MITM_REPLY_BUFFER_SIZE - 2) {
|
||||
printf("failed, block length %d doesn't fit in reply buffer size!", block_length);
|
||||
return SMBUS_ERROR_CRC;
|
||||
}
|
||||
if (block_length > length) {
|
||||
printf("failed, block length %d is larger than max result length %d!", block_length, length);
|
||||
return SMBUS_ERROR_CRC;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mitm_validate_batt_reply(mitm_reply_buffer, is_block ? block_length + 1 : length, is_block)) return SMBUS_ERROR_CRC;
|
||||
|
||||
// copy to result buffer
|
||||
for (uint i = 0; i < (is_block ? block_length : length); i++) {
|
||||
result[i] = is_block ? mitm_reply_buffer[i + 1] : mitm_reply_buffer[i];
|
||||
}
|
||||
|
||||
return is_block ? block_length : length;
|
||||
}
|
||||
|
||||
int mitm_smbus_read_text_with_override(i2c_dev_t* device, uint8_t cmd, char* result, size_t max_length, cmd_reply_override override) {
|
||||
int ret;
|
||||
|
||||
ret = mitm_smbus_read_with_override(device, cmd, result, max_length, true, override);
|
||||
if (ret < 0) return ret;
|
||||
|
||||
// search for possible null termination
|
||||
for (int i = 0; i < ret; i++) {
|
||||
if (result[i] == 0x00) return i;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
#include "smbus.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -60,3 +61,8 @@ int mitm_generate_reply_crc(uint8_t* buffer, uint8_t crc_index, bool is_block);
|
||||
|
||||
void init_mitm();
|
||||
void mitm_loop();
|
||||
|
||||
|
||||
// like the smbus read functions but applies an override
|
||||
int mitm_smbus_read_with_override(i2c_dev_t* device, uint8_t cmd, uint8_t* result, size_t length, bool is_block, cmd_reply_override override);
|
||||
int mitm_smbus_read_text_with_override(i2c_dev_t* device, uint8_t cmd, char* result, size_t max_length, cmd_reply_override override);
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Benjamin Wiegand
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
#include "override.h"
|
||||
#include "config_override.h"
|
||||
|
||||
|
||||
cmd_reply_override get_read_command_reply_override(uint8_t cmd) {
|
||||
return config_get_read_command_reply_override(cmd);
|
||||
}
|
||||
|
||||
bool defused_use_read_command_reply_override(uint8_t cmd) {
|
||||
return config_defused_use_read_command_reply_override(cmd);
|
||||
}
|
||||
|
||||
bool uart_use_read_command_reply_override(uint8_t cmd) {
|
||||
return config_uart_use_read_command_reply_override(cmd);
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Benjamin Wiegand
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
#include "mitm.h"
|
||||
#include <stdint.h>
|
||||
|
||||
cmd_reply_override get_read_command_reply_override(uint8_t cmd);
|
||||
|
||||
bool defused_use_read_command_reply_override(uint8_t cmd);
|
||||
bool uart_use_read_command_reply_override(uint8_t cmd);
|
||||
Reference in New Issue
Block a user