Blog:
Amateur Radio Services of:
Main Projects:
Stable/Old Projects:
Blog:
Amateur Radio Services of:
Main Projects:
Stable/Old Projects:
Packet radio shell scripting (© dl3sjb) can be used to implement automated operations on the packet radio network using the well-known UNIX scripting language.
Shell scripting involves chaining several UNIX commands together to accomplish a task. For example, you might login into the packet radio node, perform several commands and then use the output (i.e. 'find dl3sjb' ⇒ 'dl3sjb found on db0sao') to react interactively. I'll show you how to do this below. This is not a shell programming HOW-TO. We assume you are into it. If not, http://steve-parker.org/sh/sh.shtml (ENGLISH) -OR- http://de.wikibooks.org/wiki/Linux-Kompendium:_Shellprogrammierung (DEUTSCH) may be a good starting point.
Preparing LINUX:
First we need to define a 'deamon' that connects the LINUX shell with XNET on application level. The methodology behind this is pretty basic:
Let's get it on. The line starting with 'call' contains the most important point: we connect d1mmy (local XNET), write all data into '/tmp/ax25.log', read from '/tmp/pipe1' and write all 'errors' to the null device (waste bucket).
root@OpenWrt:~# cd /tmp root@OpenWrt:~# mkfifo pipe1 root@OpenWrt:~# ls -al pipe1 prw-r--r-- 1 root root 0 Apr 3 02:33 pipe1 root@OpenWrt:~# call -r ax0 d1mmy 1>/tmp/ax25.log 0</tmp/pipe1 2>/dev/null & root@OpenWrt:~# ps | grep "call" 500 root Z [call] root@OpenWrt:~# echo -e "\r" >pipe1 root@OpenWrt:~# ps | grep "call" 524 root 420 R call -r ax0 d1mmy root@OpenWrt:~# cat ax25.log GW4PTS AX.25 Connect v1.11 (X)NET/LINUX/MIPSel V1.39 => root@OpenWrt:~#
Once the packet radio connection is established, 'call' permanently polls 'pipe1' for new inputs. In order to avoid cpu time interferences with other processes , we need to decrease 'call's' process priority using 'renice'. This little program alters the priority of any process and sets the priority to any value in the range PRIO_MIN (-20) to PRIO_MAX. Useful priorities are: 20 (the affected processes will run only when nothing else in the system wants to), 0 (the ``base'' scheduling priority), anything negative (to make things go very fast).
SYNOPSIS: renice <priority> <pid>
root@OpenWrt:~#renice 20 524 524: old priority 0, new priority 20 root@db0sao_home0:/usr/local/icqcq# root@OpenWrt:~#
Note: 'renice' is not part of the standard image, please download it from here renice.gz, gunzip it and place it under /bin. It is not mandatory to use 'renice', but recommended. 'Reince' may become a part of future images.
root@OpenWrt:~# cd /bin root@OpenWrt:/bin# ls -al renice -rwxr--r-- 1 root root 8000 Nov 11 21:14 renice root@OpenWrt:/bin#
In the following, the basic communication procedure is explained. Bottom line: 'echo' what you would type in a packet radio terminal into 'pipe1' (in binary mode ⇒ 'echo -e') and read what you would see in the terminal window from '/tmp/ax25.log' using 'cat'.
root@OpenWrt:~# call -r ax0 d1mmy 1>/tmp/ax25.log 0</tmp/pipe1 2>/dev/null & root@OpenWrt:~# echo -e "\r" >/tmp/pipe1 root@OpenWrt:~# cat /tmp/ax25.log GW4PTS AX.25 Connect v1.11 *** Connected to d1mmy Rawmode (X)NET/LINUX/MIPSel V1.39 => root@OpenWrt:~# echo -e "find dg8ngn" >/tmp/pipe1 root@OpenWrt:~# cat /tmp/ax25.log => *** route: found DG8NGN via DB0FHN root@OpenWrt:~#
If you now were to throw all commands into a shell script, just execute this script kin order to process the data automatically.
Example: this script connects the local XNET, executes the “find” command and then waits for either a successful find - OR - stops after 10 seconds. At the end it disconnects from the local XNET.
root@OpenWrt:~# vi /tmp/ax_connect_and_find.sh #!/bin/sh # by DL3SJB # What does it do? # It connects via ax25d to local XNET and attempts to find a user using the "find" command. # If found, it sends a message to the user telling him that his buddy has been found. call -r ax0 d1mmy 1>/tmp/ax25.log 0</tmp/pipe1 2>/dev/null & sleep 1 echo -e "find $1" >/tmp/pipe1 grep "*** route" /tmp/ax25.log >/tmp/ax25found.log while test -f /tmp/ax25found.log do if [ "`cat /tmp/ax25found.log|head -c9`" = "*** route" ] then echo -e "`cat /tmp/ax25found.log`" rm -rf /tmp/ax25found.log else grep "*** route" /tmp/ax25.log >/tmp/ax25found.log let i=$i+1 sleep 1 if [ $i -eq 10 ] then i=0 echo -e "*** not found." rm -rf /tmp/ax25found.log fi fi done echo -e "q" >pipe1 root@OpenWrt:~# chmod 755 /tmp/ax_connect_and_find.sh root@OpenWrt:~# /tmp/ax_connect_and_find.sh dg8ngn *** route: found DG8NGN via DB0FHN root@OpenWrt:~# /tmp/ax_connect_and_find.sh test *** not found. root@OpenWrt:~#
Note: Whenever you end the packet radio connection with 'echo -e “q” >pipe1 ', the 'call' program no longer runs in the background. It will be ended. So you need to restart 'call' whenever you intend to establish another connection.
Conclusion: any type of shell script can use all packet radio resources using the above-described methodology. Various application are possible, such as “ICQ for packet radio” - OR - automatic “message of the day” publication in the node's connect text, etc. The only down-side of this is that 'call' polls the FIFO. This is not the most efficient way of operation. On the other hand, the setup is working on any LINUX and does not require special software (other than 'renice' if you intend to ensure free cpu time for other time critical processes on your OPENWRT device). PRSS is not limited to OPENWRT.
Have fun.
Jens, DL3SJB, IPRT, DARC P42, April 2008
root@DB0SAO_1:~# dmesg usb 1-2: new full speed USB device using uhci_hcd and address 8 usb 1-2: configuration #1 chosen from 1 choice pl2303 1-2:1.0: pl2303 converter detected usb 1-2: pl2303 converter now attached to ttyUSB0 root@DB0SAO_1:~#
root@DB0SAO_1:/usr/local/xnet# cat AUTOEXEC.NET attach SDEV0 SRPM 0 1 38400 /dev/ttyUSB0
* (1) CONNECTED to 0:DB0SAO via DL3SJB * (X)NET/LINUX/MIPSel V1.39 =>p po name interface baud txd per w dup dam duo con bit/s 0 DB0LEL 0 SDEV0 SRPM 19200tr 55 255 7 1 0 0 7 4367 =>
BusyBox v1.4.2 (2008-02-28 05:09:35 CET) Built-in shell (ash) Enter 'help' for a list of built-in commands. _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M KAMIKAZE (7.09) ----------------------------------- * 10 oz Vodka Shake well with ice and strain * 10 oz Triple sec mixture into 10 shot glasses. * 10 oz lime juice Salute! --------------------------------------------------- root@DB0SAO_1:~# root@DB0SAO_1:~# call -r ax0 db0sao GW4PTS AX.25 Connect v1.11 (X)NET/LINUX/MIPSel V1.39 18.02.09 09:06:30 DL3SJB-8 de DB0SAO :>l Link to dst Q/T rtt tx connect tx rx txq/rxq rr+% bit/s 3:DB0LEL 17 F 1 1/1 0 45d 23h 682K 684K 100/100 0.1 1221 5:DB0PRT 3 F 15 5/6 0 3d 57m 9.7K 9.7K 99/99 1.4 722 18.02.09 09:06:32 DL3SJB-8 de DB0SAO :> root@DB0SAO_1:~#
#!/bin/sh mkfifo pipe1 call -r -s dl3sjb-1 ax0 db0sao dl3sjb 1>./logfile.txt 0<pipe1 2>/dev/null & echo -e "~0" >pipe1 echo -e "l" >pipe1 echo -e "q" >pipe1 sleep 10 echo "`grep "DB0LEL" logfile`" exit 3:DB0LEL 17 F 1 1/1 0 45d 23h 682K 684K 100/100 0.1 1221
root@OpenWrt:/mnt/harddisk/wrt54gs/icqcq.new# ./ax_icq_users ------------------------------------- System: initating icq session on Sat Feb 21 09:59:43 CET 2009. user: dk7td buddies: *** route: found DL8SDL-8 via DB0SAO *** dl3sjb-1 not found. *** route: found DB0XHI via DB0PRT root@OpenWrt:/mnt/harddisk/wrt54gs/icqcq.new#
7:fm ICQCQ to DB0SAO via DL3SJB ctl SABM+ 7:fm DB0SAO to ICQCQ via DL3SJB* ctl UA- 7:fm ICQCQ to DB0SAO via DL3SJB ctl I00^ pid F0 [11] f dl8sdl-8 7:fm DB0SAO to ICQCQ via DL3SJB* ctl I10^ pid F0 [54] (X)NET/TNC3 V1.39 28.02.09 10:02:32 ICQCQ de DB0SAO :> 7:fm DB0SAO to ICQCQ via DL3SJB* ctl I11^ pid F0 [37] 28.02.09 10:02:32 ICQCQ de DB0SAO :> 7:fm DB0SAO to ICQCQ via DL3SJB* ctl RR1+ 7:fm ICQCQ to DB0SAO via DL3SJB ctl RR2- 7:fm DB0SAO to ICQCQ via DL3SJB* ctl I12^ pid F0 [75] *** route: found DL8SDL-8 via DB0SAO 28.02.09 10:02:32 ICQCQ de DB0SAO :> 7:fm DB0SAO to ICQCQ via DL3SJB* ctl RR1+ 7:fm ICQCQ to DB0SAO via DL3SJB ctl RR3- 7:fm ICQCQ to DB0SAO via DL3SJB ctl DISC+ 7:fm DB0SAO to ICQCQ via DL3SJB* ctl UA-
root@OpenWrt:/usr/local/xnet# cat aprs.sh #!/bin/sh mkfifo pipe 2>/dev/null call -r -s dl3sjb-7 ax0 db0fhn-5 dl3sjb db0sao igate 1>blubber 0<pipe 2>/dev/nul l & echo -e "\r" >pipe echo -e "~0" >pipe sleep 12 a="`cat blubber|tail -c 80|grep "*** Disconnected" -`" if [ "$a" != "" ] then exit fi a="`grep "Port full" blubber`" if [ "$a" != "" ] then exit fi echo -e "user DL3SJB-7 pass xxxxx vers UI-Glue 1.0 filter m/1" >pipe sleep 4 #echo -e "DL3SJB>APU25N,TCPIP*:@212131z4836.12N/00917.93E_225/000g000t045r000p01 0P000h88b10319" >pipe echo -e "DL3SJB-6>APU25N,TCPIP*:`cat /tmp/APRSWX_FILE.txt`" >pipe echo -e "\r" >pipe echo "DL0SIN>APRSBW,TCPIP*:;OVP42/P26*000000!4839.24N\00856.42ER Jd. DO 19:00 OV -Stammtisch,Schlossstuben" >pipe echo -e "\r" >pipe pause 1 echo -e "~." >pipe ./ax_push "~." pipe sleep 1 kill `ps | grep "call -r -s dl3sjb-7"|head -c5` 2>/dev/null kill `ps | grep "ax_push" |head -c5` 2>/dev/null #sleep 2 exit #kill `ps |grep "call"|head -c5` #kill `ps |grep "aprs.sh"|head -c5` #exit root@OpenWrt:/usr/local/xnet#
root@OpenWrt:/usr/local/xnet# (sleep 10; echo quit; sleep 2) | call -r ax0 db0sao GW4PTS AX.25 Connect v1.11 *** Connected to db0sao Rawmode (X)NET/TNC3 V1.39 18.02.09 10:21:19 DL3SJB-1 de DB0SAO :> 73! *** Cleared root@OpenWrt:/usr/local/xnet#