Skip to content
This repository has been archived by the owner on Aug 21, 2018. It is now read-only.

SSH to RPi through USB Tethering #66

Open
timecomplexity opened this issue Jul 4, 2017 · 4 comments
Open

SSH to RPi through USB Tethering #66

timecomplexity opened this issue Jul 4, 2017 · 4 comments
Assignees

Comments

@timecomplexity
Copy link
Member

It looks like @Yurockkk has figured out a way to ssh via Bluetooth and laid it out in this document. Please read through this if you have not already.

I am working with a Raspberry Pi B+ model, and therefore do not have built-in bluetooth (as our end-users might also not have equipped on their machines), so I've been researching methods to connect through USB tethering.
Unfortunately, I could only get this to work when the RPi was connected to the actual wifi rather than the USB tethering. But I believe that this is a step in the right direction, by assigning a static name that adapts to dynamic IP. I believe that this has something to do with localization. The range for the name seems to only work on the RPi itself when it is USB tethered. I'm sure there is a way around this.

Set Up RaspberryPi for Headless Operation (USB Tethering WIP)

Following a suggestion on this Stack Overflow:

1. Turn on RaspberryPi and tether it to phone to use phone's internet connection seamlessly.

2. Following this guide on your RaspberryPi:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install avahi-daemon
sudo insserv avahi-daemon

3. Then we need to create a service and restart it. Create the service with:

sudo nano /etc/avahi/services/multiple.service

4. Place this text into the file you're creating:

<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
        <name replace-wildcards="yes">%h</name>
        <service>
                <type>_device-info._tcp</type>
                <port>0</port>
                <txt-record>model=local</txt-record>
        </service>
        <service>
                <type>_ssh._tcp</type>
                <port>22</port>
        </service>
</service-group>

5. Restart the service with

sudo /etc/init.d/avahi-daemon restart

Testing on a Windows machine

If you're testing on a windows machine, you might have to install Bonjour to test raspberrypi.local. If you're testing on a Unix machine, you can skip these steps.

Then we need to add an exception to the firewall to open the 5353 UDP port. You can do this by looking at this guide and selecting UDP port and specifying 5353.

After these steps, we must grant internet access to mDNSresponder.exe so that we can use multicast over the local subnet. You can do this a similar way by creating a rule for both inbound and outbound. Simply select Program this time, and locate mDNSResponder.exe which I found in C:\Program Files (x86)\Bonjour.


Test Connection

Try out ping raspberrypi.local and it should return successful packets. If it does not, it's likely because of the issue of it being tethered via USB.
If this is the case, try turning off the USB tethering and connecting the RasberryPi to the wifi and attemping to ping and connect again. It should work this time around.


Additional Stuff

I feel like I am getting very close, I would appreciate anyone who wants to test this out themselves. Especially anyone with a very solid understanding of networks. I am afraid that I am a bit lacking in that regard, as far as complex connections go. As I stated before, I got everything to work perfectly when the RPi was connected to the wifi. I could simply use ssh pi@raspberrypi.local on my Linux machines and in PuTTY on windows.

Is there a way for us to somehow "route" the SSH through the phone's IP first and then use raspberrypi.local from there?

I thought that this link had an interesting concept. The LCD screen is not practical for our uses, nor is the audio component. But maybe we can use it to draw inspiration.
http://www.instructables.com/id/How-a-headless-Raspberry-Pi-can-tell-you-its-IP-ad/

@timecomplexity
Copy link
Member Author

This is a comment I made on #62 and I thought it should be here on this issue as it adds some extra details to what I'm currently working on.

I have been jotting down some notes over the past week and I thought I would post those here along with some links that perhaps we could look at which could potentially help out with multiple aspects of the project. I'm posting a lot, so it is probably also best to put it here so it can be laid out and digested.


This should return proper ip address, or if the third part is left out ( the grep call), we can generate a list of each one:

# Creates the RPi IP and assigns it to a variable
PIIP=$(ifconfig | perl -nle 's/dr:(\S+)/print $1/e' | grep 192)

# Make the variable an environmental variable so that child shells may use it
export PIIP

Alternatively, create a script:

#piip.sh
PIIP=$(ifconfig | perl -nle 's/dr:(\S+)/print $1/e' | grep 192)
echo $PIIP

And then to make the system available on the system, we can do the following commands:

sudo cmod 755 piip
sudo mv /path/to/script.sh /usr/local/bin/piip

To make the process simpler, you may follow these steps to test it out on your own RaspberryPi.

STEPS:

  1. In a terminal, type: nano
  2. With nano now open, create the script file.
#!/bin/bash
	
#piip.sh
# Creates the RPi IP and assigns it to a variable
# Without running grep, it will print out all IP address options
PIIP=$(ifconfig | perl -nle 's/dr:(\S+)/print $1/e' | grep 192)
		
# Make the variable an environmental variable so that child shells may use it.
# Uncomment this line if you want it to export every time.
# export PIIP

# Print IP to screen.
echo $PIIP
  1. Press Ctrl + O. Enter a filename such as piip and press enter.
  2. In the terminal window, enter sudo chmod 755 piip to set proper permissions for the script.
  3. Move the script so that it can be used universally. mv /path/to/script/piip /usr/local/bin/piip

Now you will be able to use the piip command.

The problem remains finding what the IP address of the RPi is without having to be directly connected already to the pi (headlessly). That's what I'm trying to look into with the Network Service Discovery API. If anyone wants to give this a shot, please do so!


Links

NOTE: After reading this article, it appears that there is Bluetooth tethering on some phones.
https://www.howtogeek.com/170302/the-htg-guide-to-tethering-your-android-phone/

1

I found this Stack Overflow question somewhat helpful, specifically this part:
image
So, it looks like there is a specific DHCP address range for the pi to tether to, from 192.168.42.1 to 192.168.42.255, which may be useful information to have.
https://stackoverflow.com/questions/11506160/how-to-get-the-system-ip-address-after-usb-tethering-of-android-phone

2

This Stack Overflow question didn't have a ton of responses, but it did present these two documents--WifiP2pDeviceList and PeerListListener which according to the answer might be necessary to use.
image

3

We might be able to use this open source project to figure out how to look at all the available wifi devices. I had some difficulty getting it to build on Windows because it doesn't use Gradle to build, but rather it uses Ant. I will give it a shot on my Linux laptop when I get the chance. If anyone wants to test it out themselves (probably on a Unix machine) that would be fantastic. It looks like it could be promising.
https://github.com/rorist/android-network-discovery

4

Network Service Discovery API
https://developer.android.com/training/connect-devices-wirelessly/nsd.html

5

An example code snippet of Android using NSD and a server socket. This could potentially be really useful, but it looks like it relies on a class called CommonHelper so it might not work for us.
https://gist.github.com/richard1122/b8fc8dd2f4b74e7975cd

@timecomplexity
Copy link
Member Author

One thing I am going to research is automatically sending a file from the RPi to the phone when the phone is plugged in. We would be able to write the IP from the RPi to the file and then read it from an app on the phone and that would essentially do the same thing. I'm not sure if this is possible but it's worth looking into. Since it would be a one line text document transferring it would not take up many resources.

@timecomplexity
Copy link
Member Author

I'm posting this here because I found these useful:

Android API

https://developer.android.com/reference/java/net/NetworkInterface.html
https://developer.android.com/reference/android/net/wifi/WifiManager.html

Stack Overflow suggestion

https://stackoverflow.com/questions/43478586/checking-tethering-usb-bluetooth-is-active


It appears that on android, we can run ls /sys/class/net/ | grep "rndis" to check if the tethering is enabled. I'm trying to implement that into my app now, which I will be adding to the repository soon.

@timecomplexity
Copy link
Member Author

I have made a lot of progress with this.
I will be using the ip neighbor command to retrieve the IP address of the RPi.
Up until today, I didn't even know it existed.

You can see my updated repository here:
Piiper

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

No branches or pull requests

1 participant