From 8e2262e1214f37ee9a8f8d787553fd65aa9367e1 Mon Sep 17 00:00:00 2001 From: Chris Blake Date: Sat, 15 Jun 2024 09:49:11 -0500 Subject: [PATCH] fix: and add data to ubnteeprom (#10) * Fixup incorrect device serial # * Add more system info about the NVRs * Start using ubnteeprom in more spots * Also do some minor BT house cleaning --- .../filesystem/usr/lib/init/boot/ubnt-bt.sh | 33 +--- .../lib/python3/dist-packages/ubnthelpers.py | 13 +- tools/ubnteeprom/main.go | 187 +++++++++++++++--- 3 files changed, 163 insertions(+), 70 deletions(-) diff --git a/overlay/filesystem/usr/lib/init/boot/ubnt-bt.sh b/overlay/filesystem/usr/lib/init/boot/ubnt-bt.sh index 969303e..1fd33de 100755 --- a/overlay/filesystem/usr/lib/init/boot/ubnt-bt.sh +++ b/overlay/filesystem/usr/lib/init/boot/ubnt-bt.sh @@ -52,9 +52,11 @@ function main(){ # unvr: nothing to do here ;; ea1a) + # unvr usb_based_init ;; - ea20|ea50|ea51) + ea20) + # unvr-pro gpio_num=$(find_gpio_on_expander 0 0020 8) if [ $gpio_num -lt 0 ]; then return 5 @@ -62,26 +64,6 @@ function main(){ gpio_reset $gpio_num uart_based_init /dev/ttyS3 "/lib/firmware/csr8x11/csr8x11-a12-bt4.2-patch-2018_uart.psr" ;; - ea2c|ea15|ea11|ea32) - gpio_reset 37 - uart_based_init /dev/ttyS1 "/lib/firmware/csr8x11/csr8x11-a12-bt4.2-patch-2018_uart.psr" - ;; - ea3d|ea3e) - gpio_num=$(find_gpio_on_expander 3 0029 13) - if [ $gpio_num -lt 0 ]; then - return 5 - fi - gpio_reset $gpio_num - uart_based_init /dev/ttyAMA1 "/lib/firmware/csr8x11/pb-207-csr8x11-rev7-flowcontrol.psr" "flow" - ;; - a678|a690|a69a) - gpio_reset 490 - usb_based_init - ;; - e990) - gpio_reset 306 - usb_based_init - ;; *) return 4 ;; @@ -166,13 +148,4 @@ function uart_based_init(){ hciconfig ${BT_DEVICE} up } -function usb_based_init(){ - hciconfig ${BT_DEVICE} up; hciconfig ${BT_DEVICE} up - sleep 1 - bccmd psset -r 0x$((BT_DEVICE_NUM+1)) 0x${BT_MAC:6:2} 00 0x${BT_MAC:10:2} 0x${BT_MAC:8:2} 0x${BT_MAC:4:2} 00 0x${BT_MAC:2:2} 0x${BT_MAC:0:2} - sleep 2 - hciconfig ${BT_DEVICE} down - hciconfig ${BT_DEVICE} up; hciconfig ${BT_DEVICE} up -} - main "$@" diff --git a/overlay/filesystem/usr/lib/python3/dist-packages/ubnthelpers.py b/overlay/filesystem/usr/lib/python3/dist-packages/ubnthelpers.py index 534e996..ac4d3ac 100644 --- a/overlay/filesystem/usr/lib/python3/dist-packages/ubnthelpers.py +++ b/overlay/filesystem/usr/lib/python3/dist-packages/ubnthelpers.py @@ -5,17 +5,6 @@ from functools import lru_cache A handful of Ubiquiti Unifi device specific functions """ -UBNTHAL_PATH = "/proc/ubnthal/system.info" - - @lru_cache(None) def get_ubnt_shortname() -> str: - try: - with open(UBNTHAL_PATH, "r") as f: - ubnthal_model = [i for i in f.readlines() if i.startswith("shortname=")][0] - return ubnthal_model.lstrip("shortname=").rstrip("\n") - except FileNotFoundError: - print( - f"Error: unable to open {UBNTHAL_PATH}; is the ubnthal kernel module loaded?!" - ) - raise + return os.popen("ubnteeprom -systeminfo -key shortname").read().rstrip("\n") diff --git a/tools/ubnteeprom/main.go b/tools/ubnteeprom/main.go index c7d7e32..f40f542 100644 --- a/tools/ubnteeprom/main.go +++ b/tools/ubnteeprom/main.go @@ -10,6 +10,86 @@ import ( "strings" ) +// Type for device map +type UBNTSysMap struct { + name, shortname, cpu, sysid string +} + +var UBNTDeviceMap = []UBNTSysMap{ + { + name: "Unifi-NVR-PRO", + shortname: "UNVRPRO", + cpu: "AL324V2", + sysid: "ea20", + }, + { + name: "UniFi-NVR-4", + shortname: "UNVR4", + cpu: "AL324V2", + sysid: "ea16", + }, + { + name: "UniFi-NVR-4", + shortname: "UNVR4", + cpu: "AL324V2", + sysid: "ea1a", + }, +} + +type UBNT_Return_Values struct { + name, value string +} + +// Store our board vars +var UBNT_Board_Vars = []string{ + "format", + "version", + "boardid", + "vendorid", + "bomrev", + "hwaddrbbase", + "EthMACAddrCount", + "WiFiMACAddrCount", + "BtMACAddrCount", + "regdmn[0]", + "regdmn[1]", + "regdmn[2]", + "regdmn[3]", + "regdmn[4]", + "regdmn[5]", + "regdmn[6]", + "regdmn[7]", +} + +// Store our systeminfo vars +var UBNT_SystemInfo_Vars = []string{ + // "cpu", + // "cpuid", + // "flashSize", + // "ramsize", + "vendorid", + "systemid", + // "shortname", + "boardrevision", + "serialno", + // "manufid", + // "mfgweek", + // "qrid", + // eth*.macaddr (generated mac's for all eth interfaces) + // "device.hashid", + // "device.anonid", + // "bt0.macaddr", + "regdmn[]", + // "cpu_rev_id", +} + +// Store our ubnt-tools id vars +var UBNT_Tools_vars = []string{ + "board.sysid", + "board.serialno", + "board.bom", +} + // Type for EEPROM structure type EEPROM_Value struct { name, description, vtype string @@ -17,7 +97,8 @@ type EEPROM_Value struct { } // Build our BOARD eeprom structure -var BOARD = []EEPROM_Value{ +var EEPROM = []EEPROM_Value{ + // START BOARD DATA { name: "format", description: "EEPROM Format", @@ -137,11 +218,8 @@ var BOARD = []EEPROM_Value{ length: 0x2, vtype: "hex", }, -} - -// Build our SYSTEM_INFO eeprom structure -var SYSTEM_INFO = []EEPROM_Value{ - // Missing values: + // END BOARD DATA + // START SYSTEM INFO // cpu // cpuid // flashSize (this is static in unifi's kernel module -_-) @@ -172,7 +250,7 @@ var SYSTEM_INFO = []EEPROM_Value{ name: "serialno", description: "Serial Number", offset: 0x0, - length: 0x5, + length: 0x6, vtype: "hex", }, // manufid @@ -190,10 +268,8 @@ var SYSTEM_INFO = []EEPROM_Value{ vtype: "hex", }, // cpu_rev_id -} - -// Build our vars that are similar to running ubnt-tools id -var UBNT_TOOLS = []EEPROM_Value{ + // END SYSTEM INFO + // START UBNT TOOLS ID { name: "board.sysid", description: "Device Model/Revision Identifier", @@ -201,13 +277,13 @@ var UBNT_TOOLS = []EEPROM_Value{ length: 0x2, vtype: "hex", }, - { - name: "board.serialno", - description: "Serial Number", - offset: 0x0, - length: 0x5, - vtype: "hex", - }, + // board.name (handled by UBNTDeviceMap) + // board.shortname (handled by UBNTDeviceMap) + // board.subtype + // board.reboot # Time (s) + // board.upgrade # Time (s) + // board.cpu.id + // board.uuid { name: "board.bom", description: "Board Bill of Materials Revision Code", @@ -215,6 +291,16 @@ var UBNT_TOOLS = []EEPROM_Value{ length: 0xC, vtype: "str", }, + // board.hwrev + { + name: "board.serialno", + description: "Serial Number", + offset: 0x0, + length: 0x6, + vtype: "hex", + }, + // board.qrid + // END UBNT TOOLS ID } func check(e error) { @@ -291,20 +377,65 @@ func eeprom_read(vl []EEPROM_Value, f *os.File, key string) string { } } -func return_values(values []EEPROM_Value, file string, filter string) { +func return_values(rtype string, file string, filter string) { + var okeys []string + var ourboard UBNTSysMap + var ret_data []UBNT_Return_Values + // Open EEPROM for read only f, err := os.Open(file) defer f.Close() check(err) - // If select is set, select our item, else return all + // Start with our sysid for extra vars, pull it out of our list + board_sysid := eeprom_read(EEPROM, f, "systemid") + for _, board := range UBNTDeviceMap { + if board.sysid == board_sysid { + ourboard = board + break + } + } + + // did we find our device? + if ourboard.name == "" { + fmt.Printf("Error: Unknown board sysid of %s! This device is not yet supported.\n", board_sysid) + os.Exit(1) + } + + // Load in the right list of keys to itterate over, add static keys if we got em + if rtype == "board" { + okeys = UBNT_Board_Vars + } else if rtype == "system" { + okeys = UBNT_SystemInfo_Vars + ret_data = append(ret_data, UBNT_Return_Values{name: "cpu", value: ourboard.cpu}) + ret_data = append(ret_data, UBNT_Return_Values{name: "shortname", value: ourboard.shortname}) + } else if rtype == "tools" { + okeys = UBNT_Tools_vars + ret_data = append(ret_data, UBNT_Return_Values{name: "board.name", value: ourboard.name}) + ret_data = append(ret_data, UBNT_Return_Values{name: "board.shortname", value: ourboard.shortname}) + } + + // Populate our eeprom data for the rest of the data + for _, v := range okeys { + ret_data = append(ret_data, UBNT_Return_Values{name: v, value: eeprom_read(EEPROM, f, v)}) + } + + // Do we have a filter? if so select and return single item if len(filter) > 0 { - // Read value - fmt.Printf("%s\n", eeprom_read(values, f, filter)) + // Does our filter item exist in our ret object? + for _, v := range ret_data { + if v.name == filter { + fmt.Printf("%s\n", v.value) + return + } + } + // If we are here, our key didn't exist + fmt.Printf("Error: Invalid key %s!\n", filter) + os.Exit(1) } else { - // read all - for _, v := range values { - fmt.Printf("%s=%s\n", v.name, eeprom_read(values, f, v.name)) + // Return all items because we have no filter + for _, v := range ret_data { + fmt.Printf("%s=%s\n", v.name, v.value) } } } @@ -326,11 +457,11 @@ func main() { // Is board set? if *argboard { - return_values(BOARD, *argfile, *argfilter) + return_values("board", *argfile, *argfilter) } else if *argsystem { - return_values(SYSTEM_INFO, *argfile, *argfilter) + return_values("system", *argfile, *argfilter) } else if *argtools { - return_values(UBNT_TOOLS, *argfile, *argfilter) + return_values("tools", *argfile, *argfilter) } else { // Tell user noting was submitted fmt.Fprintf(os.Stderr, "Error Invalid usage of %s:\n", os.Args[0])