Skip to content
Draft
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
2 changes: 1 addition & 1 deletion completions/bash/framework_tool
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ _framework_tool() {

case "${cmd}" in
framework_tool)
opts="-v -q -t -f -h --flash-gpu-descriptor --verbose --quiet --versions --version --features --esrt --device --compare-version --power --thermal --sensors --fansetduty --fansetrpm --autofanctrl --pdports --info --meinfo --pd-info --pd-reset --pd-disable --pd-enable --dp-hdmi-info --dp-hdmi-update --audio-card-info --privacy --pd-bin --ec-bin --capsule --dump --h2o-capsule --dump-ec-flash --flash-ec --flash-ro-ec --flash-rw-ec --intrusion --inputdeck --inputdeck-mode --expansion-bay --charge-limit --charge-current-limit --charge-rate-limit --get-gpio --fp-led-level --fp-brightness --kblight --remap-key --rgbkbd --ps2-enable --tablet-mode --touchscreen-enable --stylus-battery --console --reboot-ec --ec-hib-delay --uptimeinfo --s0ix-counter --hash --driver --pd-addrs --pd-ports --test --test-retimer --boardid --force --dry-run --flash-gpu-descriptor-file --dump-gpu-descriptor-file --nvidia --host-command --generate-completions --help"
opts="-v -q -t -f -h --flash-gpu-descriptor --verbose --quiet --versions --version --features --esrt --device --compare-version --power --thermal --sensors --fansetduty --fansetrpm --autofanctrl --pdports --info --meinfo --serialnums --pd-info --pd-reset --pd-disable --pd-enable --dp-hdmi-info --dp-hdmi-update --audio-card-info --privacy --pd-bin --ec-bin --capsule --dump --h2o-capsule --dump-ec-flash --flash-ec --flash-ro-ec --flash-rw-ec --intrusion --inputdeck --inputdeck-mode --expansion-bay --charge-limit --charge-current-limit --charge-rate-limit --get-gpio --fp-led-level --fp-brightness --kblight --remap-key --rgbkbd --ps2-enable --tablet-mode --touchscreen-enable --stylus-battery --console --reboot-ec --ec-hib-delay --uptimeinfo --s0ix-counter --hash --driver --pd-addrs --pd-ports --test --test-retimer --boardid --force --dry-run --flash-gpu-descriptor-file --dump-gpu-descriptor-file --nvidia --host-command --generate-completions --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand Down
3 changes: 2 additions & 1 deletion completions/fish/framework_tool.fish
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ complete -c framework_tool -l power -d 'Show current power status of battery and
complete -c framework_tool -l thermal -d 'Print thermal information (Temperatures and Fan speed)'
complete -c framework_tool -l sensors -d 'Print sensor information (ALS, G-Sensor)'
complete -c framework_tool -l pdports -d 'Show information about USB-C PD ports'
complete -c framework_tool -l info -d 'Show info from SMBIOS (Only on UEFI)'
complete -c framework_tool -l info -d 'Show info from SMBIOS'
complete -c framework_tool -l serialnums -d 'Show info about system serial numbers'
complete -c framework_tool -l pd-info -d 'Show details about the PD controllers'
complete -c framework_tool -l dp-hdmi-info -d 'Show details about connected DP or HDMI Expansion Cards'
complete -c framework_tool -l audio-card-info -d 'Show details about connected Audio Expansion Cards (Needs root privileges)'
Expand Down
3 changes: 2 additions & 1 deletion completions/zsh/_framework_tool
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ _framework_tool() {
'--thermal[Print thermal information (Temperatures and Fan speed)]' \
'--sensors[Print sensor information (ALS, G-Sensor)]' \
'--pdports[Show information about USB-C PD ports]' \
'--info[Show info from SMBIOS (Only on UEFI)]' \
'--info[Show info from SMBIOS]' \
'--serialnums[Show info about system serial numbers]' \
'--pd-info[Show details about the PD controllers]' \
'--dp-hdmi-info[Show details about connected DP or HDMI Expansion Cards]' \
'--audio-card-info[Show details about connected Audio Expansion Cards (Needs root privileges)]' \
Expand Down
7 changes: 6 additions & 1 deletion framework_lib/src/commandline/clap_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ struct ClapCli {
#[arg(long)]
pdports: bool,

/// Show info from SMBIOS (Only on UEFI)
/// Show info from SMBIOS
#[arg(long)]
info: bool,

Expand All @@ -87,6 +87,10 @@ struct ClapCli {
#[arg(long)]
meinfo: Option<Option<String>>,

/// Show info about system serial numbers
#[arg(long)]
serialnums: bool,

/// Show details about the PD controllers
#[arg(long)]
pd_info: bool,
Expand Down Expand Up @@ -552,6 +556,7 @@ pub fn parse(args: &[String]) -> Cli {
dump_gpu_descriptor_file: args
.dump_gpu_descriptor_file
.map(|x| x.into_os_string().into_string().unwrap()),
serialnums: args.serialnums,
nvidia: args.nvidia,
host_command,
}
Expand Down
27 changes: 21 additions & 6 deletions framework_lib/src/commandline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ use crate::nvme;
use crate::os_specific;
use crate::parade_retimer;
use crate::power;
use crate::serialnum::Cfg0;
use crate::smbios;
use crate::smbios::ConfigDigit0;
use crate::smbios::{dmidecode_string_val, get_smbios, is_framework};
#[cfg(feature = "hidapi")]
use crate::touchpad::print_touchpad_fw_ver;
Expand Down Expand Up @@ -226,6 +226,7 @@ pub struct Cli {
pub flash_gpu_descriptor: Option<(u8, String)>,
pub flash_gpu_descriptor_file: Option<String>,
pub dump_gpu_descriptor_file: Option<String>,
pub serialnums: bool,
pub nvidia: bool,
// UEFI only
pub allupdate: bool,
Expand Down Expand Up @@ -1542,6 +1543,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
} else if let Some(dump_path) = &args.meinfo {
let verbose = args.verbosity.0 >= log::LevelFilter::Warn;
me_info(verbose, dump_path.as_deref());
} else if args.serialnums {
serialnum_info();
} else if args.pd_info {
print_pd_details(&ec);
} else if let Some(pd) = args.pd_reset {
Expand Down Expand Up @@ -1822,7 +1825,8 @@ Options:
--fansetrpm Set fan RPM (limited by EC fan table max RPM)
--autofanctrl [<FANID>]Turn on automatic fan speed control (optionally provide fan index)
--pdports Show information about USB-C PD ports
--info Show info from SMBIOS (Only on UEFI)
--info Show info from SMBIOS
--serialnums Show info about system serial numbers
--pd-info Show details about the PD controllers
--privacy Show privacy switch statuses (camera and microphone)
--pd-bin <PD_BIN> Parse versions from PD firmware binary file
Expand Down Expand Up @@ -2091,8 +2095,7 @@ fn smbios_info() {
// Assumes it's ASCII, which is guaranteed by SMBIOS
let config_digit0 = &version[0..1];
let config_digit0 = u8::from_str_radix(config_digit0, 16);
if let Ok(version_config) =
config_digit0.map(<ConfigDigit0 as FromPrimitive>::from_u8)
if let Ok(version_config) = config_digit0.map(<Cfg0 as FromPrimitive>::from_u8)
{
println!(" Version: {:?} ({})", version_config, version);
} else {
Expand Down Expand Up @@ -2130,8 +2133,7 @@ fn smbios_info() {
// Assumes it's ASCII, which is guaranteed by SMBIOS
let config_digit0 = &version[0..1];
let config_digit0 = u8::from_str_radix(config_digit0, 16);
if let Ok(version_config) =
config_digit0.map(<ConfigDigit0 as FromPrimitive>::from_u8)
if let Ok(version_config) = config_digit0.map(<Cfg0 as FromPrimitive>::from_u8)
{
println!(" Version: {:?} ({})", version_config, version);
} else {
Expand Down Expand Up @@ -2280,6 +2282,19 @@ fn me_info(verbose: bool, dump_path: Option<&str>) {
}
}

fn serialnum_info() {
let smbios = get_smbios();
if smbios.is_none() {
error!("Failed to find SMBIOS");
return;
}
for undefined_struct in smbios.unwrap().iter() {
if let DefinedStruct::OemStrings(data) = undefined_struct.defined_struct() {
smbios::dump_oem_strings(data.oem_strings());
}
}
}

fn analyze_ccgx_pd_fw(data: &[u8]) {
if let Some(versions) = ccgx::binary::read_versions(data, Ccg3) {
println!("Detected CCG3 firmware");
Expand Down
4 changes: 4 additions & 0 deletions framework_lib/src/commandline/uefi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ pub fn parse(args: &[String]) -> Cli {
allupdate: false,
info: false,
meinfo: None,
serialnums: false,
nvidia: false,
host_command: None,
};
Expand Down Expand Up @@ -236,6 +237,9 @@ pub fn parse(args: &[String]) -> Cli {
Some(None)
};
found_an_option = true;
} else if arg == "--serialnums" {
cli.serialnums = true;
found_an_option = true;
} else if arg == "--intrusion" {
cli.intrusion = true;
found_an_option = true;
Expand Down
1 change: 1 addition & 0 deletions framework_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub mod fw_uefi;
mod os_specific;
pub mod parade_retimer;
pub mod power;
pub mod serialnum;
pub mod smbios;
mod util;

Expand Down
105 changes: 105 additions & 0 deletions framework_lib/src/serialnum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use alloc::format;
use alloc::string::{String, ToString};
use core::str::FromStr;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;

#[derive(Debug)]
pub struct FrameworkSerial {
// brand: Always FR for Framework
// format: Always A
/// Three letter string
pub product: String,
/// Two letter string
pub oem: String,
/// Development state
pub cfg0: Cfg0,
/// Defines config of that specific product
pub cfg1: char,
pub year: u16,
pub week: u8,
pub day: WeekDay,
/// Four letter/digit string
pub part: String,
}

#[repr(u8)]
#[derive(Debug, PartialEq, FromPrimitive, Clone, Copy)]
pub enum Cfg0 {
SKU = 0x00,
Poc1 = 0x01,
Proto1 = 0x02,
Proto2 = 0x03,
Evt1 = 0x04,
Evt2 = 0x05,
Reserved = 0x06,
Dvt1 = 0x07,
Dvt2 = 0x08,
Pvt = 0x09,
MassProduction = 0x0A,
MassProductionB = 0x0B,
MassProductionC = 0x0C,
MassProductionD = 0x0D,
MassProductionE = 0x0E,
MassProductionF = 0x0F,
}

#[derive(Debug)]
pub enum WeekDay {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}

impl FromStr for FrameworkSerial {
type Err = String;

// TODO: !!! PROPER ERROR HANDLING !!!
fn from_str(s: &str) -> Result<Self, Self::Err> {
let pattern =
r"FRA([A-Z]{3})([A-Z]{2})([0-9A-F])([0-9A-F])([0-9A-Z])([0-9]{2})([0-7])([0-9A-Z]{4})";
let re = regex::Regex::new(pattern).unwrap();

let caps = re.captures(s).ok_or("Invalid Serial".to_string())?;

let cfg0 = caps.get(3).unwrap().as_str().chars().next();
let cfg0 = cfg0.and_then(|x| str::parse::<u8>(&x.to_string()).ok());
let cfg0 = cfg0.and_then(<Cfg0 as FromPrimitive>::from_u8);
let cfg0 = if let Some(cfg0) = cfg0 {
cfg0
} else {
error!("Invalid CFG0 '{:?}'", cfg0);
return Err(format!("Invalid CFG0 '{:?}'", cfg0));
};
let cfg1 = caps.get(4).unwrap().as_str().chars().next().unwrap();
let year = str::parse::<u16>(caps.get(5).unwrap().as_str()).unwrap();
let year = 2020 + year;
let week = str::parse::<u8>(caps.get(6).unwrap().as_str()).unwrap();
// TODO: Decode into date
let day = match str::parse::<u8>(caps.get(7).unwrap().as_str()).unwrap() {
1 => WeekDay::Monday,
2 => WeekDay::Tuesday,
3 => WeekDay::Wednesday,
4 => WeekDay::Thursday,
5 => WeekDay::Friday,
6 => WeekDay::Saturday,
7 => WeekDay::Sunday,
_ => return Err("Invalid Day".to_string()),
};

Ok(FrameworkSerial {
product: caps.get(1).unwrap().as_str().to_string(),
oem: caps.get(2).unwrap().as_str().to_string(),
cfg0,
cfg1,
year,
week,
day,
part: caps.get(2).unwrap().as_str().to_string(),
})
}
}
Loading