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

Make gnirehtet run whenever I plug in my device #49

Closed
twoi opened this issue Oct 16, 2017 · 12 comments
Closed

Make gnirehtet run whenever I plug in my device #49

twoi opened this issue Oct 16, 2017 · 12 comments

Comments

@twoi
Copy link

twoi commented Oct 16, 2017

Currently, I have to run the command gnirehtet each time I connect my phone to my computer. Is there a way to start the gnirehtet server so it waits in the background and activates reverse tethering every time I plug my phone in?

@twoi twoi changed the title Make gnirehtet run when I plug in my device Make gnirehtet run whenever I plug in my device Oct 16, 2017
@Biswa96
Copy link

Biswa96 commented Oct 16, 2017

I found this type of feature in an app called Reverse Tethering NoRoot. But that app includes ads and paid version. It's server exe app in PC constantly running background with adb devices -l command (with small L).

adb.exe devices -l
adb fork-server server
adb.exe -s List forward tcp:port tcp:port
adb.exe -s List shell "pm grant <app_name> android.permission.WRITE_SECURE_SETTINGS"
conhost.exe 0x4

<app_name> are

  • com.floriandraschbacher.reversetethering.free for the free one.
  • com.floriandraschbacher.reversetethering.pro for the paid one.

Hope this info may help.

@rom1v
Copy link
Collaborator

rom1v commented Oct 16, 2017

It's server exe app in PC constantly running background with adb devices -l command

Yes, that's what I would like to avoid (cf #47 (comment)). At least, it won't be the default behavior.

But maybe as an alternative to gnirehtet run, we could add gnirehtet autoor something that provides this behavior.

@twoi
Copy link
Author

twoi commented Oct 17, 2017

Thanks @Biswa96 for sketching it out for lazy me.

There sure are more elegant ways to go about this, but in the meantime, the following script does the job for me (here on linux).

On startup, it fires up gnirehtet relay in the background and then, polling adb devices -l, simply does a gnirehtet start [serial] every time a device is plugged in.

#!/usr/bin/env clojure

(import 'java.lang.Runtime)

(def home-dir (java.io.File. (System/getProperty "user.home")))
(def gnirehtet-dir (java.io.File. home-dir "gnirehtet-java"))

(defn- bash-exec
  ([cmd-line] (bash-exec cmd-line nil))
  ([cmd-line home-dir]
   (let [proc (. (Runtime/getRuntime) exec (into-array [ "bash" "-c" cmd-line]) nil gnirehtet-dir)
         proc-in (java.io.BufferedReader. (java.io.InputStreamReader. (.getInputStream proc)))
         proc-err (java.io.BufferedReader. (java.io.InputStreamReader. (.getErrorStream proc)))]
     (concat (line-seq proc-in) (line-seq proc-err)))))

(defn- bash-exec-and-out
  [cmd-line home-dir]
  (doseq [line (bash-exec cmd-line home-dir)]
    (println line)))
    
(future (bash-exec-and-out "./gnirehtet relay" gnirehtet-dir))
        
(loop [last-device-set nil]
  (let [device-set (set (bash-exec "adb devices -l|sed -nre 's/^([0-9A-Za-z]+) +device .*$/\\1/p'"))
        new-devices (apply disj device-set last-device-set)]
    (doseq [device new-devices]
      (println "Newly connected device " device)
      (bash-exec-and-out (str "./gnirehtet start " device) gnirehtet-dir))
    (Thread/sleep 1000)
    (recur device-set)))

@rom1v
Copy link
Collaborator

rom1v commented Oct 17, 2017

Great, it made me discover some clojure code :)

It works for me (I just changed the gnirehtet-dir to ".").
You can also replace adb devices -l by adb devices here.

@CameronNemo
Copy link

You can do this a lot more easily with udev rules than a daemon that polls adb. Check out the android-udev package on Arch, it matches vendor IDs to detect when an Android device is plugged in.

@rom1v
Copy link
Collaborator

rom1v commented Oct 17, 2017

@CameronNemo Yes, but:

  • this is not multiplatform;
  • changing udev rules requires root access.

@twoi
Copy link
Author

twoi commented Oct 18, 2017

I rewrote above script, chiefly in order to remove the dependence on (the UNIX specific) external bash and sed commands.
@rom1v This version also features something Java is lacking: #"regex literals"

#!/usr/bin/env clojure

(def home-dir (java.io.File. (System/getProperty "user.home")))
(def gnirehtet-dir (java.io.File. home-dir "gnirehtet-java"))

(defn- exec
  ([cmd-line-args] (exec cmd-line-args nil))
  ([cmd-line-args home-dir]
   (let [proc (. (java.lang.Runtime/getRuntime) exec (into-array cmd-line-args) nil home-dir)
         proc-in (java.io.BufferedReader. (java.io.InputStreamReader. (.getInputStream proc)))
         proc-err (java.io.BufferedReader. (java.io.InputStreamReader. (.getErrorStream proc)))]
     (concat (line-seq proc-in) (line-seq proc-err)))))

(defn- gnirehtet
  [& cmd-line-args]
  (doseq [line (exec (concat ["java" "-jar" "gnirehtet.jar"] cmd-line-args) gnirehtet-dir)]
    (println line)))

(defn- replaced-only
  [s match replacement]
  (let [result (clojure.string/replace s match replacement)]
    (if (not= result s)
      result)))

(future (gnirehtet "relay"))

(loop [last-device-set nil]
  (let [adb-devices-out (exec ["adb" "devices"])
        device-set (set (filter identity (map #(replaced-only % #"^(\w+)\s+device$" "$1") adb-devices-out)))
        new-devices (apply disj device-set last-device-set)]
    (doseq [device new-devices]
      (println "Newly connected device" device)
      (gnirehtet "start" device))
    (Thread/sleep 1000)
    (recur device-set)))

@doedel
Copy link

doedel commented Nov 9, 2017

Hello I am using gnirehtet on a Linux server.

If you use it frequently udev rules does the trick pretty easy on linux.
I fire up the relay server in a tmux session (so I can look whats going on :-) when my server starts
and then have the start and stop command executed on usb unplugging or replugging.
Only down side is, you have to configure each device manually, but on the other hand, when it is done, you can even connect multiple devices automatically!

@rom1v
Copy link
Collaborator

rom1v commented Nov 9, 2017

Could you provide the udev rules for people which are interested in the same behavior, please?

@CameronNemo
Copy link

CameronNemo commented Nov 9, 2017

https://wiki.archlinux.org/index.php/Android#Adding_udev_Rules

Then add another line with a command using RUN+=

SUBSYSTEM=="usb",ATTR{idVendor}=="[VENDOR ID]",ATTR{idProduct}=="[PRODUCT ID]",RUN+="/full/path/to/gnirehtet start"

@tango25001
Copy link

tango25001 commented Nov 10, 2017

I did this with my Raspi - runs perfect with the ARM library (thx again :-) )

In /etc/udev/rules.d I put the files 85-1start.rules containing

ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="XXXX", RUN+="/home/XX/RT/start1.sh"

86-1stop.rules containing

ACTION=="remove", SUBSYSTEM=="usb", ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="XXXX", RUN+="/home/XX/RT/stop1.sh"

Both ATTRS{idVendor}=="XXXX" and ATTRS{idProduct}=="XXXX" you get for each device with lsusb when it is plugged

REBOOT to get udev reload

the stop1.sh contains

#!/bin/bash
/home/c2/RT/gnirehtet stop SERIAL

the start1.sh contains

#!/bin/bash
sleep 5
/home/c2/RT/gnirehtet start SERIAL

Further when my raspi starts I have the relay server just started automatically.

With that,
just plug the device and after 5 secs it is connected.
unplugging and the service ist stopped
replug youre device and your back online.

Hope this explains everything

rom1v thank you very very much for the great work and especially for the ARM Binary :-)

@rom1v
Copy link
Collaborator

rom1v commented Feb 6, 2018

I implemented the feature, see #47 (comment).

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

No branches or pull requests

6 participants