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

Support NixOS #52

Open
ferrine opened this issue Feb 14, 2025 · 4 comments
Open

Support NixOS #52

ferrine opened this issue Feb 14, 2025 · 4 comments

Comments

@ferrine
Copy link

ferrine commented Feb 14, 2025

Hi, thank you for your work, first of all! I'm using non standard linux, NixOS, and there are no hard coded paths and not standard /opt/ or /usr/.

As investigating the binary, I found that it uses couple of hard coded paths that were not so trivial to fix and there were still some missing pieces.

for more context this is how I attempted to approach hardcoded paths issue.

{ stdenv
  , lib
  , openssl
  , pciutils
  , usbutils
  , libmbim
  , modemmanager
  , bbe
  , procps
  , makeWrapper
  , autoPatchelfHook
  , fetchFromGitHub
}:
let
  version = "2.1.3";
  pname = "lenovo-wwan-unlock";
in
stdenv.mkDerivation {
  inherit version pname;
  src = fetchFromGitHub {
    owner = "lenovo";
    fetchSubmodules = true;
    repo = pname;
    rev = "v${version}";
    hash = "sha256-dlJDlJXanMPNw8kyK4B4X/L4l7om2Lep9LdylPbth/A=";
  };
  nativeBuildInputs = [
    bbe
    makeWrapper
    autoPatchelfHook
  ];
  autoPatchelfIgnoreMissingDeps = [
  ];
  buildInputs = [
    stdenv.cc.cc
    openssl.out
    pciutils
    usbutils
    libmbim
    modemmanager
  ];
  buildPhase = ''
    # create xx - runtime path for `openat' syscalls of configservice_lenovo
    # move basically all stuff there
    # you can check `strings configservice_lenovo | grep /opt/` and strace it
    # to figure out it is the issue
    mkdir -p $out/xx/fcc_lenovo/lib
    mv *.so $out/xx/fcc_lenovo/lib/
    tar -zxf sar_config_files.tar.gz -C $out/xx/fcc_lenovo/

    # patching configservice_lenovo strings so they point to existing locations
    # 1) string lenth should be unchanged.
    # 2) Not sure about DPRConfig, it
    #    was not created for me but point it to var instead
    # 3) for lspci and lsusb binary uses sh call that evaluates env vars
    #    we can change it to better ones
    mkdir -p $out/bin/
    bbe -e 's%/opt/fcc_lenovo/.DPRConfig.xml%/var/lib/lenovo/.DPRConfig.xml%' \
        -e 's%/opt/fcc_lenovo/DPRConfig.xml.sig%/var/lib/lenovo/DPRConfig.xml.sig%' \
        -e 's%$SNAP/usr/bin/lspci%$SNAP_PCI/bin/lspci%' \
        -e 's%$SNAP/usr/bin/lsusb%$SNAP_USB/bin/lsusb%' \
        configservice_lenovo -o configservice_lenovo1
    bbe -e 's%/opt/fcc_%./xx/fcc_%' configservice_lenovo1 -o $out/bin/configservice_lenovo
    chmod +x $out/bin/configservice_lenovo

    wrapProgram $out/bin/configservice_lenovo \
      --set SNAP_PCI ${pciutils} \
      --set SNAP_USB ${usbutils} \
      --chdir $out \
      --prefix PATH : ${lib.makeBinPath [
        modemmanager
        procps
      ]}
  '';
}

module config for nixos

{pkgs, lib, config, ...}:
let
  cfg = config.hardware.lenovo-wwan-unlock;
in
  {
    options.hardware.lenovo-wwan-unlock.package =
      lib.mkPackageOption pkgs "lenovo-wwan-unlock" {};
    config = {
      system.activationScripts.lenovoVarLib =
      ''
        # Lenovo var Dir for WWAN SAR config
        mkdir -p /var/lib/lenovo/
        chmod 755 /var/lib/lenovo/
        chown root:root /var/lib/lenovo/
      '';
      systemd.services.lenovo-wwan-unlock = {
        description = "SAR config for Lenovo PCs WWAN";
        documentation = [ "https://github.com/lenovo/lenovo-wwan-unlock" ];
        wantedBy = [ "multi-user.target" ];
        after = [ "ModemManager.service" ];
        serviceConfig = {
          Type = "simple";
          User="root";
          ExecStart = "${cfg.package}/bin/configservice_lenovo";
          ExecReload = "${pkgs.coreutils}/bin/kill -s HUP $MAINPID";
          RestartSec = "20";
          Restart = "on-failure";
        };
      };
    };
  }

This is weird, but it made the binary working. I wonder is it trivial to remove path hardcoding from /opt and /usr/bin/ ? Is there any easy solution on your side so no one attempts to reverse engineer the binary for personal use?

PS what should I do with DPRConfig.xml, is it needed at all?

UPD Editing this message using the modem

-- Boot efe246efae5e44e292e303b3d6bfe551 --
Feb 14 13:39:44 nixos systemd[1]: Started SAR config for Lenovo PCs WWAN.
Feb 14 13:39:54 nixos configservice_lenovo[2139]: public_decrypt completed
Feb 14 13:39:55 nixos configservice_lenovo[2139]: SAR Config setting is success
Feb 14 13:39:55 nixos configservice_lenovo[2139]: No need to update.
Feb 14 13:39:55 nixos systemd[1]: lenovo-wwan-unlock.service: Deactivated successfully.
Feb 14 13:39:55 nixos systemd[1]: lenovo-wwan-unlock.service: Consumed 113ms CPU time, 8M memory peak, 2.8M read from disk.
Feb 14 13:41:16 nixos systemd[1]: Started SAR config for Lenovo PCs WWAN.
Feb 14 13:41:16 nixos configservice_lenovo[3990]: public_decrypt completed
Feb 14 13:41:17 nixos configservice_lenovo[3990]: SAR Config setting is success
Feb 14 13:41:17 nixos configservice_lenovo[3990]: No need to update.
Feb 14 13:41:17 nixos systemd[1]: lenovo-wwan-unlock.service: Deactivated successfully.
Feb 14 13:47:00 nixos systemd[1]: Started SAR config for Lenovo PCs WWAN.
Feb 14 13:47:01 nixos configservice_lenovo[5329]: public_decrypt completed
Feb 14 13:47:01 nixos configservice_lenovo[5329]: SAR Config setting is success
Feb 14 13:47:01 nixos configservice_lenovo[5329]: No need to update.
Feb 14 13:47:01 nixos systemd[1]: lenovo-wwan-unlock.service: Deactivated successfully.
default dev ppp0 proto static scope link metric 700 
default dev wwp0s20f0u8i1 scope link src 169.254.9.250 metric 1001003 
10.64.64.64 dev ppp0 proto kernel scope link src 100.123.13.111 
169.254.0.0/16 dev wwp0s20f0u8i1 scope link src 169.254.9.250 metric 1003
@ferrine ferrine changed the title Support NIxOS Support NixOS Feb 14, 2025
@lxwulf
Copy link

lxwulf commented Feb 15, 2025

Hey there 👋,

This looks great, though I do not know much about NixOS and, if I'm correct, NixOS expression code. My home is Python. 😊

Anyway, I think for sure It's a good Idea to consider to support also other platforms than Ubuntu and Fedora, though the processing and maintaining of project will be more complicated I guess. 🤔

Nonetheless, I would appreciate having one platform more. So this gets a +1 from me.
Though, I'm just a community member, so I can't decide if yes or no but @nitinexclusively will know for sure what to do next. 😊

Greetings LxWulf ✌️

🐧🐺

@ferrine
Copy link
Author

ferrine commented Feb 17, 2025

Cool, for integrating into NixOS ecosystem, in a nutshell, it does not need much but baking $FCC_LENOVO_HOME env variable that defaults to /opt/fcc_lenovo into binaries. On top of this everything can be seamlessly bootstrapped in NixOS.

In NixOS there is a clear separation on what is mutable and what is immutable. Assuming $FCC_LENOVO_HOME is read only, any files created on disk reside on /var partition. I do not know if you assume /opt/fcc_lenovo writable in the code, but it has to be taken into account

@nitinexclusively
Copy link
Collaborator

@ferrine Thanks for reaching out !
I am not much aware about NixOS but please find my reply as mentioned below:

This is weird, but it made the binary working. I wonder is it trivial to remove path hardcoding from /opt and /usr/bin/ ? Is there any easy solution on your side so no one attempts to reverse engineer the binary for personal use?

Since , this FCC unlock binary is created to unlock Modem in accordance with FCC compliant. So , we need to support it in official way rather then providing any tweak or reverse engineering. Sorry , if any inconvenience caused.

PS what should I do with DPRConfig.xml, is it needed at all?
May I know, from where you have received DPRConfig.xml file , as its not part of this released package via github?

We are only officially supporting Ubuntu and fedora .
Since there are many different flavor of Linux , So, its challenging to create package for each flavors.
However , we are creating package of other Linux favors based on strong business request and for limited products only.

Thanks

@ferrine
Copy link
Author

ferrine commented Feb 19, 2025

Thanks for the reply, I got this Filename by

strings unlock.so | grep /opt/

No official support is fine. Having fully functional laptop is great. If no changes are possible to the hardcoded paths, it is fine to just keep this issue visible so other NixOS people can adopt the solution and improve their quality of life on Lenovo hardware

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants