diff --git a/flake.nix b/flake.nix index f768299..b60af57 100644 --- a/flake.nix +++ b/flake.nix @@ -9,6 +9,30 @@ system = "x86_64-linux"; }; in { + packages.x86_64-linux = { + # Define the default package, which will build the C++ app + default = pkgs.stdenv.mkDerivation { + pname = "cli"; + version = "0.1.0"; + + # Source directory containing the C++ code + src = ./.; + + # Build dependencies (e.g., compilers) + buildInputs = [ pkgs.gcc pkgs.libusb1 ]; + + # Build commands + buildPhase = '' + mkdir -p $out/bin + g++ -o $out/bin/cli src/cli.cpp src/usb_thingy.cpp -lusb-1.0 + ''; + + # Optional: installation phase, if additional steps are needed + #installPhase = '' + # # Nothing extra needed here; the binary is already in $out/bin + #''; + }; + }; devShells.x86_64-linux = { default = pkgs.mkShell { propagatedBuildInputs = with pkgs; [ diff --git a/src/cli.cpp b/src/cli.cpp index 5b96fec..f3c32c3 100644 --- a/src/cli.cpp +++ b/src/cli.cpp @@ -1 +1,116 @@ -#include \ No newline at end of file +#include "usb_thingy.h" + +#include +#include +#include + +#define CHK(X) \ + if ((r = (X)) != 0) \ + return r; + +int main(int argc, char *argv[]) +{ + // Define the long options + static struct option long_options[] = { + {"help", no_argument, nullptr, 'h'}, + {"battery-capacity", no_argument, nullptr, 'c'}, + {"battery-status", no_argument, nullptr, 's'}, + {nullptr, 0, nullptr, 0}}; + + /*static struct option long_options[] = { + {"help", no_argument, nullptr, 'h'}, + {"battery-capacity", no_argument, nullptr, 'c'}, + {"battery-status", required_argument, nullptr, 's'}, + {nullptr, 0, nullptr, 0} + };*/ + + int option_index = 0; + int opt; + bool getBatteryStatus = false; + bool getBatteryCapacity = false; + + if (Connection::getInstance().findDevice()) + { + std::cerr << "ERROR: Device not found!"; + return 1; + } + + // Parse command-line arguments + while ((opt = getopt_long(argc, argv, "hcs:", long_options, &option_index)) != -1) + { + switch (opt) + { + case 'h': + std::cout << "Usage: " << argv[0] << " [options]\n" + << "Options:\n" + << " -h, --help Show this help message\n" + << " -c, --battery-capacity Print battery capacity\n" + << " -s, --battery-status Print battery status\n"; + return 0; + case 'c': + getBatteryCapacity = true; + break; + case 's': + getBatteryStatus = true; + break; + case '?': // Handle unknown options + std::cerr << "Unknown option. Use --help to see the usage.\n"; + return 1; + default: + break; + } + } + + // Display the parsed arguments + if (getBatteryCapacity) + { + unsigned char dat[8]; + memset(dat, 0, 8 * sizeof(unsigned char)); + + unsigned char _data[8] = {0x05, 0x90, 0, 0, 0, 0, 0, 0}; + + ssize_t r; + CHK(Connection::getInstance().open()); + CHK(Connection::getInstance().setReport(0x0305, (unsigned char *)_data, 8)); + CHK(Connection::getInstance().getReport(0x0305, (unsigned char *)dat, 8)); + CHK(Connection::getInstance().close()); + + if (dat[2] == 0x10 && dat[3] == 0x01) + return -1; + + std::cout << (int)dat[3] << "\n"; + return 0; + } + if (getBatteryStatus) + { + unsigned char dat[8]; + memset(dat, 0, 8 * sizeof(unsigned char)); + + unsigned char _data[8] = {0x05, 0x90, 0, 0, 0, 0, 0, 0}; + + ssize_t r; + CHK(Connection::getInstance().open()); + CHK(Connection::getInstance().setReport(0x0305, (unsigned char *)_data, 8)); + CHK(Connection::getInstance().getReport(0x0305, (unsigned char *)dat, 8)); + CHK(Connection::getInstance().close()); + + if (dat[2] == 0x10 && dat[3] == 0x01) + { + std::cout << "loading" + << "\n"; + return 0; + } + + std::cout << "discharging" + << "\n"; + return 0; + } + + // Handle non-option arguments + for (int i = optind; i < argc; i++) + { + std::cout << "Non-option argument: " << argv[i] << "\n"; + } + + return 0; +} \ No newline at end of file