redirect serial port output as bash command with Xbee and RPI - bash

My setup is complicated and I think I have a clear way ahead, but please let me know if you see a better way to accomplish my end state of using a terminal window over Xbee. My use case is that RPI #1 has internet connectivity, but RPI #2 does not, and I want to fully control and access RPI #2 via RPI #1 over Xbee.
I have x2 Raspberry Pi 3B+ and am using x2 Xbee Pro S3B modules to communicate between the RPIs over Xbee USB Development Shields. The Xbees show on the RPIs as /dev/ttyUSB0. I want to use the Xbees as a transportation layer to the RPIs, much like 802.11/15 or plain old ethernet would be used in a headless situation with bash. The Xbees are running at 115200 baud rate, and are named and setup via the X-CTU tool. I have no illusions of high speed data, but want to "see" RPI #2 terminal on RPI #1, the same as when SSH is accomplished with traditional transport layers.
I am able to use the Xbees in Transparent Mode, and send plain text with Screen, Minicom, "echo "text here" > /dev/ttyUSB0", and "cat < /dev/ttyUSB0". Despite the ability to pass messages, I want to use these plain text messages as bash input. For example, when I pass the command ls via any of the three methods listed from RPI 1, I want to have bash exectue "ls" on RPI 2, not just see it listed on the screen for RPI 2.
I've found several tools for Xbee, but don't want to wire up the GPIO pins and go that method; I want to use the Xbees as simple transport, nothing more. How do I pass text from /dev/ttyUSB0 to bash as a command, and see the results? Short of a more direct route, I'm considering using crontabs and an executable file that is erased and re-written to accomplish this task, but feel that is a last, very ineffective, method.
Is there some tool I am missing that does this already? Can I "screen" over a serial port as command line and serial I/O simultanously?
I found pyserial, which could allow for a TCP binding to the /dev/ttyUSB0 port, but am not sure if that is the right way to go or not. As of now, my code is as simple as
RPI #1:
echo "ls" > /dev/ttyUSB0
RPI #2:
cat < /dev/ttyUSB0

I was able to send and recieve commands from command line of a local (although remoted) XBee host to a remote (secondary, off net) Xbee host. I found the answer when I started looking at how serial devices could open a login terminal, and arrived at the getty tool. Here are my setup instructions for Transparent Mode use, I am still trying to get python-xbee and other tools to work to allow for the same concept, but via API mode. Note that the below instructions are a 95% solution, but should get the common user to a solid way ahead. I am not the original author of the steps below in their format, but found each step and combined them through various other Q&A forums to arrive at a solution:
First, acquire Digi Xbee X-CTU software (does not install on ARM devices such as Raspberry or Odroid):
XCTU:
Install from the following Digi.com link, but navigate to the corrresponding software FTP link:
https://www.digi.com/support/productdetail?pid=3352&type=drivers
Linux 64 Bit: ftp://ftp1.digi.com/support/utilities/40002881_R.run
Linux 32 Bit: ftp://ftp1.digi.com/support/utilities/40002880_R.run
Windows: ftp://ftp1.digi.com/support/utilities/40003026_T.exe
Mac: ftp://ftp1.digi.com/support/utilities/40003026_T.exe
Install X-CTU Via:
sudo wget ftp://ftp1.digi.com/support/utilities/40002880_R.run
sudo mv 40002881_R.run xctu_64bit.run
sudo chmod +x xctu_64bit.run
sudo ./xctu_64bit.run
Find X-Bee Device:
make sure Xbee is not plugged into a hub, power will be too little, recognizable via the below error, YMMV:
dmesg | grep ttyUSB0
and returning error: [ 228.800021] ftdi_sio ttyUSB0: failed to get modem status: -32
lsusb -v -d 0403:6001
sudo nano /boot/cmdline.txt
change the console tty device from AMA to USB, then for the kgdboc, which allows the remote end to watch the boot process, add/make match as appropriate
console=ttyUSB0,115200 kgdboc=ttyUSB0,115200
sudo nano /etc/inittab
make sure to uncomment (remove #) if present, change tty from AMA to USB
T0:23:respawn:/sbin/agetty -L ttyUSB0 115200 vt100
On Ubuntu x86 system, use X-CTU via
sudo ./XCTU.desktop
update firmware to the latest version
currently 8075 for the Pro S3B, then set baud rate to 115200 on each device
other xbees on in the vicinity can be updated by using a local xbee via X-CTU, then setting the api mode to “api mode with escapes”. Note that Transparent Mode should be used unless you have an indepth knowlege to make API mode work. I started with Transparent Mode to demonstrate the below works, but have since moved to API mode to gain the enhanced send-recieve control capabilities (pending a working version as of this writing).
do the same steps for all the devices that will be used on the network; once the local device is complete, other remote devices can be updated if visible (close enough).
Close out X-CTU and add the current user to the dialout group via:
sudo usermod -a -G dialout root
reboot then:
Setup Minicom Via:
sudo aptitude install minicom
minicom -s
serial port setup
a, set to /dev/ttyUSB0, then hit enter
e, set baud rate to 115200, then hit enter
hit enter again to close the window and arrive at the configuration page of minicom
select to save as dfl, followed by enter
then move to exit, and hit return
test connection to a locally connected device via
three plus symbols without hitting return
if it replies “ok” in a few seconds or less, all is well
OR Screen:
screen /dev/ttyUSB0
again, if you see a login prompt, you are connected. Note that screen is probably the best choice for most users; it has the inherent quality of ease of use (when compared to Minicom), handles low bandwidth connections with ease, and stays alive despite a disconnect from remote host. Ctl+a and then k will disconnect.
Install Coreutils to add more options than Minicom (Screen is also advisable):
sudo aptitude install coreutils && screen
stty -F /dev/ttyUSB0 -a
this will check serial port capabilities and settings
Communicate with your devices:
Note you interact with your network on a local machine with an X-Bee plugged in, or on a remote device you SSH over the internet, as long as it has an X-Bee attached. Also, note that the below settings to rc.local weren't keeping my settings after a reboot; this is a work in progress. I was setting them manually until I got automation worked out.
Also, I added rc.local to the RPI manually, the how-to for that is out there somewhere:
sudo systemctl stop serial-getty#ttyAMA0.service
sudo systemctl disable serial-getty#ttyAMA0.service
sudo systemctl enable serial-getty#ttyUSB0.service
sudo nano /etc/rc.local
add the below before exit 0
The stty line is twice because it has been noted that the first instance changes the reported baud rate to 9600, the second to 115200. If you are doing this manually, do a “stop” then re-do the start command to receive the prompt. This could be automated; I will update this post with a process monitor.
stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb raw
stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb raw
sudo systemctl start serial-getty#ttyUSB0.service
Then, use Minicom, Screen, or "cat" and "watch" to view messages sent. When using Minicom you will receive a login prompt via the above directions. As previously stated, I am still trying to get this working smoothly for API mode, but at least I know I have connectivity and can do basic command & control via the command line remotely with Transparent Mode, including running command line programs and commands. Transparent Mode does not offer any enhanced RF propagation correction techniques, hence my desire to get API mode working; RSSI values and error correction would be nice.

Related

How to capture the traffic of Genymotion Emulator with tcpdump?

I have an android device (simulated with Genymotion on top off virtualBox) on my host computer(ubuntu).
which interface I should capture to have both incoming and outgoing traffic of android devices?
Download tcpdump for android from here: https://www.androidtcpdump.com/android-tcpdump/downloads
Use the following commands to setup all the things.
adb root
adb remount
adb push ./tcpdump /system/xbin/tcpdump
ToUse:
adb shell
tcpdump -D
tcpdump -vv -i any -s 0 -w /sdcard/dump.pcap
adb pull /sdcard/dump.pcap .
Then analyze the pcap file in Wireshark if you want.
This answer might help https://stackoverflow.com/a/48062718/20107. It's using Wireshark but it should be easy to adapt to tcpdump.

Raspberry: Every binary : command not found

When booted, my raspberry checks if the program called reader is running. If it is, it does nothing, but if not, it runs it.
After a bunch of time, a few hours (between 2 and 4 hours) the raspberry is completely lost. I can't connect with SSH, the program that ran is not running anymore, etc.
I tried to run a SSH client to get the error while i'm connected to it so I can watch what's in the dmesg and so on, but here is what I get :
pi#raspberrypi:~ $ tail -f /var/log/syslog
-bash: tail: command not found
pi#raspberrypi:~ $ sudo tail -f /var/log/syslog
-bash: /usr/bin/sudo: No such file or directory
pi#raspberrypi:~ $ ls
-bash: ls: command not found
pi#raspberrypi:~ $ /bin/ls
-bash: /bin/ls: No such file or directory
pi#raspberrypi:~ $
pi#raspberrypi:~ $ cd /bin/
pi#raspberrypi:/bin $ ./ls
-bash: ./ls: No such file or directory
If I stop the SSH session and try to connect again :
pi#raspberrypi:/bin $ logout
Connection to 10.25.168.59 closed.
root#me:/home/user# ssh pi#10.25.168.59
Read from socket failed: Connection reset by peer
I can ping the raspberry pi and NMAP says something hilarious :
Nmap scan report for 10.25.168.59
Host is up (-0.087s latency).
MAC Address: xx:xx:xx:xx:xx:xx (Raspberry Pi Foundation)
Then if I unplug the raspi and plug it back, I can connect back to it and here are the logs from syslog : http://sprunge.us/lSSnj7
We can see at 11:17:08 it's booting but nothing more.
And here's maybe a thing that can help : The pi has the red light constantly ON while the green one blinks following that pattern : on for 8s, off for 0.5s
For information, my program is written in C, it opens an USB port (it is a barcode scanner) and does nothing about shutdown or reboot the machine.
I've already checked for memory peaks, CPU peaks, zombies processes, but nothing. I use only 60 Mb of RAM on 1 Gb, CPU is used at less than 2%. 110 tasks and 0.03 load average.
Why does the raspberry freezes or reboots (without killing the SSH session) but does not completely reboot, because my reader is not launched again ?
Any help would be very much appreciated. Thanks
Maybe some hardware problems on the SD card ?
These "not found" look like when the system is in really bad shape after a hardware failure or a sudo rm -rf /*

How to automate ISO installation (iDrac for DELL server)?

I need to automate ISO installation on Dell server. For such systems we have host itself and another ip for the iDrac management interface.
The flow that I need to automate is:
Connect a USB with ISO DD image to the system
reboot the host (can be done via ssh directly or from iDrac virtual console that connects to the host)
After the reboot, I don't have ssh connection to host but in the KVM (virtual console) I can still see the rebooting process and communicate with it. for example pressing F2 F11 etc.
Change the BIOS setup to start from USB and complete the installation by filling all required parameters.
For that purpose I tried using the pywinauto (we have a RobotFramework + Python2.7), but the problem that I'm facing that the KVM (virtual console) is recognized as one window (with no children or other controls).
So I can type keys like: ENTER SPACE Arrows(Up,Down,Left,Right) TAB F2 F11... but I'm not able to get or read the content of the console shown in the screen, what enforce me to use hardcoded steps and use sleeps between steps.
Something else that I thought that can help is connecting to the iDrac via SSH and with racadm api to try to get that content, but I couldn't find a subcommand that gives such information.
So am out of options, I know about other tool called Sikuli that works with image recognition which I used before to automate iOS and I found the reliability of it hard to trust so am not going to try it again.
Please advise if there is such a tool that can extract that console content.
BTW, the console can be opened with different plug-in types such: Native, Java, Html5 (only in iDrac 8+), even with Html5 the control that contains that console is a <canvas> that I can’t really extract anything from it (beside that I need to cover older versions of iDrac)
I work for Dell. There are a couple options. Simplest is to use remote racadm from your script. You can install racamd on any Windows or Linux machine. You can use racadm to dispaly boot order then change it and boot the host.
http://topics-cdn.dell.com/pdf/idrac7-8-lifecycle-controller-v2.30.30.30_Reference%20Guide4_en-us.pdf
racadm -r <idrac-ip> -u <user> -p <passwd> get BIOS.BiosBootSettings
racadm -r <idrac-ip> -u <user> -p <passwd> set BIOS.BiosBootSettings.HddSeq
racadm -r <idrac-ip> -u <user> -p <passwd> serveraction powerup
Other options are wsman and redfish you can learn about those on the Dell Tech Center wiki http://de.community.dell.com/techcenter/w/wiki
Place the desired ISO on a Windows share
Install racadm tools on your workstation
https://www.dell.com/support/home/us/en/04/drivers/driversdetails?driverid=8gmf6
In command line, give the iDRAC command to mount the shared ISO to the server where you want to install the iso content:
racadm -r remote_machine_iDRAC_IP -u idrac_user -p idrac_password remoteimage -c -u remote_share_user -p remote_share_passwd -l //remote_share_IP/iso/<iso_name>
Change boot order:
racadm -r remote_machine_iDRAC_IP -u idrac_user -p idrac_password remoteimage -c -u remote_share_user -p remote_share_passwd set idrac.ServerBoot.FirstBootDevice VCD-DVD
Use powercycle if machine machine is powered up, or powerup if it is powered down:
racadm -r remote_machine_iDRAC_IP -u idrac_user -p idrac_password remoteimage -c -u remote_share_user -p remote_share_passwd serveraction powercycle/powerup
When you connect to the iDRAC console it should boot (assuming the ISO is a bootable image) to the OS installation screen.
Do the installation and right before restarting it following the OS deployment disconnect the mounted ISO:
racadm -r remote_machine_iDRAC_IP -u idrac_user -p idrac_password remoteimage -d
selecting on f11 boot manager and then click on shot bios menu
and then selected bootable usb. it is doing automatic

How to delete a password from keychain with a shell command?

I wanted to make a shell script that connects to a hidden wireless network on my macbook pro by creating a network. However, I only want to connect to that network when I want to and to prevent airport from connecting automatically I'll have to delete the network's password from keychain.
So far I have:
networksetup -setairportnetwork en1 $ssid $networkpassword
networksetup -removepreferredwirelessnetwork en1 $ssid
Im also aware that in OSX 10.7 the security command can modify the keychain.
Anyway I would appreciate any help someone can give me. I'm also willing to use applescript or something else if it works. Thank you.
I figured it out. The command I used is:
sudo security delete-generic-password -l $ssid "/Library/Keychains/System.keychain"
sudo was needed because this keychain is located in the systems library. security also contains a lot more delete and useful commands and you can specify how you want to indicate the location in this command.
edit: I was having some trouble using this command and went back and learned I could use another command to not remember the network at all which I would have used before if I had found it. With this option you can do a wealth of things with your adapter along with the networksetup option.
Here is my final script which first runs as root. then it changes the system preferences to not remember new networks. Then it disconnects from any current networks. Then it adds the new network. Lastly, it makes the system remember new wifi networks.
sudo -i
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport prefs RememberRecentNetworks=NO
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -Z
networksetup -setairportnetwork en1 $ssid $password
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport prefs RememberRecentNetworks=YES

Execute Command after VM Booted

I've gotten sick of how many steps it takes me to get started in the morning. Yes it only takes me a few minutes to start up my whole environment, but I'd really rather just run a single command on boot-up and be ready to go immediately.
I'm writing an app on Rails connected to SqlServer. To develop for it I have a local version of the DB I use on a VM. My manual process goes like this:
Run VirtualBox.
Start the VM.
When the VM is done booting:
Open terminal
Run `rails s`
When rails is done starting:
open browser
navigate to localhost:3000 and start developing
Run Sublime
I'd love to do this in one script:
VirtualBox Windows7 &
sublime &
google-chrome &
But I can't figure out how to run this command only once the VM is done booting:
gnome-terminal --working-directory=git/my_project --tab -e 'rails s' --tab -e 'git status'
Also, it'd be nice (but not necessary) to have chrome start after rails s has succeeded.
Is this even possible?
I'm not opposed to polling, but it feels like this is something VirtualBox should be able to do a bit more naturally.
EDIT
From Comment:
I'm using Host-Only network with two Bridged Interfaces (one for wireless and one for wired) available. (It allows me to use the VM whether or not I'm connected to a network, and lets me freely switch between wired and wireless without noticing the difference).
Here is how I would do:
In the VM, create a script which will find the default gateway, & keep pinging to it. & add it to user's startup. (needs parsing of ipconfig /all which can be done with vbscript/python.)
In host, look at the network interface between host & VM. Find the default gateway on host (parse route -n output in bash script). Since both use same physical interface, the gateway would be same (assuming NAT & ONE physical interface). Use tcpdump, to wait for the ping packets to the gateway.
"Default gateway" was chosen because that was something host & VM can find out independent of each other. Other alternative was to hard-code host's address.
After the host tcpdump on host exits, it means that the VM is alive & booted upto windows desktop.
I looked into this line of inquiry before, and I think Devil's Pie is the closest you can get to setting that up:
http://burtonini.com/blog/computers/devilspie
You could try starting with this (VBoxManager startvm):
How to automatically start and shut down VirtualBox machines?
and then look at some working scripts to add to your init.d and/or rc.local once your VM is up to finish the rest of the job in order:
Get To Know Linux: The /etc/init.d Directory
I needed to orchestrate something similar. I'm using a Windows VM (guest) as a proxy (it runs a Windows-only corporate VPN client) for my Linux laptop (host). The approach is to fully automate the guest and wait until it's ready:
The host must have no funky routes (yet)
The VM starts and runs a powershell script (via Windows Task Scheduler, run-on-startup) that connects the VPN client and sets up ICS (Internet Connection Sharing, basically routing).
The host now adds funky routes that send some traffic via the VM's host-only interface. If it added these routes too soon, step 2 would not work.
The VM also runs squid (http proxy) and its port is NAT port forwarded from the host, so localhost:3128 actually goes to the guest. So a curl using this proxy goes to the corporate network and indicates whether the guest is fully up and connected.
(Squid is also useful as a backup to this complicated but very convenient mechanism, I can still ssh via corkscrew, etc)
So, I run this script on the host (simplified version shown):
#!/bin/bash
VM=vm #Name of the Virtual Machine
SCRIPT_DIR=/some/dir
PROXY_ADDRESS=localhost:3128
REMOTE_CURL_HOST=any.corporate.hostname
function waitloop() {
echo -n "Waiting to hear from $REMOTE_CURL_HOST "
while ! curl -s -m 5 --proxy $PROXY_ADDRESS $REMOTE_CURL_HOST > /dev/null ; do
echo -n .
sleep 10
done
echo "!"
}
# a separate script that takes down my routes, you may not need this.
bash $SCRIPT_DIR/network-config-vboxnet0.sh down
# error is OK if it's already running
vboxmanage startvm $VM
waitloop && bash $SCRIPT_DIR/network-config-vboxnet0.sh up && echo "Completed"
Essentially, the script waits until curl works through the VM.

Resources