0%

最近一段时间里经过大量阅读和实际操作,我对于AX.25有了更深入的了解,Pat等程序的使用配置也逐渐熟练。今天看到了一个名为Pat Winlink 2M Packet 1200 baud Setup的视频教程,KM4ACK在树莓派上利用AX.25, direwolf和Pat实现了packet radio连接Winlink网络。经过比较,该教程思路和操作与我在R3300-M盒子上的操作基本一致,这证明利用电视盒子实现packet radio是完全可行的。这批文章对之前几篇的关键点进行了总结,并补充了遗漏内容。

内核

为了在Linux中进行AX.25操作,内核必须支持AX.25。之前我在Manjaro ARM中使用的linux-odroid内核没有预编译对应模块,自行编译内核足足花费了5个小时,不过一次成功。另外经过联系内核维护者,AX.25内核模块已在配置文件中启用,,如无意外linux-odroid在下一个更新便会原生支持AX.25,倘若如此就不需要自己编译内核了。

ax25tools

https://github.com/ve7fet/linuxax25/releases/tag/ax25tools-1.0.4 由ax25apps, ax25tools, libax25 三部分构成,需要分别编译安装,方法之前已详细介绍。有几点需要特别说明:

  1. ax25tools合集中提供的 kissattach 等程序会在 /usr/local/etc/ax25 目录下寻找 axports 等配置文件;
  2. make install 没有将这些配置文件复制到 /usr/local/etc/ax25 目录下,所以需要自己手动建立配置文件;
  3. Pat会在 /etc/ax25 目录下寻找 axports ,作为变通手段,可以建立软连接: sudo ln -s /usr/local/etc/ax25 /etc/ax25

Direwolf

编译安装方法之前已详细介绍,额外几点补充说明:

  1. 需要启用 avahi 服务,否则 Direwolf 会提示 DNS-SD: Avahi: Failed to create Avahi client: Daemon not running
    sudo systemctl enable --now avahi-daemon.service
    
  2. 合理设置以避免使用root权限运行Direwolf。我使用了FT232将串口转换成USB(淘宝买的U5-Link),在Manjaro中对应设备为 /dev/ttyUSB0
    $ ls /dev/ttyUSB0
    Permissions  Size User Group Date Modified Name
    crw-rw----  188,0 root uucp   3 Jun 20:59  /dev/ttyUSB0
    
    为了能够以普通用户身份读写 /dev/ttyUSB0 ,需要将当前用户(我的用户名是marly) 添加到 uucp 这个组中:
    $ sudo usermod -aG uucp marly
    $ id marly
    uid=1000(marly) gid=1000(marly) groups=1000(marly),3(sys),90(network),98(power),998(wheel),996(audio),994(input),991(lp),987(storage),986(uucp),985(video),984(users),970(sambashare)
    
    通过id命令可以得知当前用户已成功加入到 uucp 组中。 重新登录SSH以使改动生效!

另外Direwolf每次启动都会创建 /tmp/kisstnc 这个指向实际pts设备的符号连接。所以如果你之前用root身份运行过direwolf,direwolf就无法新建 /tmp/kisstnc ,把**/tmp/kisstnc删除一次就可以了。以后创建的/tmp/kisstnc**不会再遇到这种权限问题。

KISS TNC配置

测试Direwolf时,发现Direwolf提示

Are you using AX.25 for Linux?  It might be trying to use a modified version of KISS which uses the channel field differently than the original KISS protocol specification.  The solution might be to use a command like "kissparms -c 1 -p radio" to set CRC none mode. Another way of doing this is pre-loading the "kiss" kernel module with CRC disabled: sudo /sbin/modprobe -q mkiss crc_force=1

运行 sudo kissparms -c 1 -p wl2k 即可。

下步计划

计划研究利用LinBPQ搭建Winlink网关,Winlink Gateway on a Raspberry Pi LinBPQ 这个视频应该会很有帮助。不知道本地的火腿能不能帮忙实测packet radio效果。

另外 Configuring Linux AX.25 推荐阅读,有助于加深对AX.25工作方式及使用方法的理解。

Direwolf配合Pat使用时遇到了一点小小的问题,Direwolf提示以下信息:

<<< Data frame from KISS client application, port 8, total length = 18
  000:  80 84 90 64 ac 94 ae e0 84 90 64 ac 94 ae 61 3f  ...d......d...a?
  010:  0a d0                                            ..
Invalid transmit channel 2 from KISS client app.

Are you using AX.25 for Linux?  It might be trying to use a modified
version of KISS which uses the channel field differently than the
original KISS protocol specification.  The solution might be to use
a command like "kissparms -c 1 -p radio" to set CRC none mode.
Another way of doing this is pre-loading the "kiss" kernel module with CRC disabled:
sudo /sbin/modprobe -q mkiss crc_force=1

Direwolf已经给出了提示,修复方式也很简单:

sudo kissparms -c 1 -p wl2k

kissparams是用来配置KISS TNC的工具。具体言之,用来配置通过kissattach命令连接到AX.25 端口的KISS TNC。kissparam通过packet接口与KISS TNC通讯,不干涉AX.25数据流,所以在对AX.25端口进行操作时,可以通过kissparam随时改变KISS TNC的配置,而不需要重新绑定端口与TNC(很方便!)。

-c为crc类型。0 = auto, 1 = none, 2 = flexnet, 3 = smack
-p为端口,同kissattach

其他几个选项自行查看man文档吧。让人介意的是-e选项,即 FEC error correction level 。具体如下:

Sets the FEC error correction level in a DSP card based modem (KISS parameter 8). Larger correction level means better noise resistance, but slower  throughput  on  a good connection. This is an experimental feature found in a QPSK modem for the Motorola DSP56001 based DSP4 and EVM cards only.

FEC,顾名思义 Forward Error Correction,Direwolf文档中在FX.25中有所提及。通过FEC技术,可以显著提升抗干扰能力,缺点是干扰较小传输良好时,通信速率比不使用FEC的连接慢,这是传输冗余信息作为纠正码的代价。可惜这个特性目前仅支持基于摩托罗拉DSP56001的DSP4和EVM,而且局限于QPSK调制。看来目前只能借助Direwolf来实现FX.25。

参考了man手册和Direwolf文档,同时结合实际操作验证。

名称

kissattach, spattach —— 用于连接一个KISS或者6PACK接口

概要

kissattach [-b] [-6] [-l] [-m mtu] [-v] tty port [inetaddr]
spattach [-b] [-l] [-m mtu] [-v] tty port [inetaddr]

编者按:kissattach默认使用KISS模式,spattach默认使用6PACK模式,此外并无分别。

描述

将一个KISS或者6PACK接口连接到KISS或者6PACK模式的TNC,就像一条普通的tty连接线一样。这个程序在执行后会自动变成后台进程,可以通过给这个后台进程发送 SIGTERM 以终止。

kissattach从 axports 文件中读取port以及相关的参数(编者补充:传统上axports路径为/etc/ax25,kissattatch也会在这里寻找axports,不过我自己编译安装的ax25toos会在/usr/local/etc/ax25/目录下寻找。另外make install后不知为何axports等配置文件没有被复制到这些位置,需要自己手动复制)。如果axports中speed是一个非零值,那么这个值会被用作串口通信速度,如果是0则意味着没有设置速度(貌似是废话)。paclen是设备的MTU值,可以通过-m选项覆盖。

tty在传统上是与KISS或者6PACK TNC连接的串口,不过也可以和伪终端(编者按:这是我们需要的,和Direwolf生成的伪终端连接)或者例如SCC卡这种KISS端口模拟器连接。kissattach也支持BSD和Unix98风格的伪终端。如果tty参数是 /dev/ptmx ,那么Kissattach就会自动适应Unix98的行为。对于Unix98伪终端,从tty名称是不可预见的,所以kissattach会在标准输出上另起一行输出对应从伪终端的名字。

port就是从axports文件中读取的portname值。

inetaddr参数是可选的,它是这个新接口的IP地址。有时这个选项不能省略,不过总体而言给这个接口分配IP地址的意义不大。(编者按:可以通过给接口分配IP地址来测试是否与Direwolf连接成功,该方法参考自Direwolf文档)

选项

-6 使用6PACK而非KISS。使用spattach调用时该选项默认开启。

-i inetaddr 设定接口的IP地址。接受hostname或者类似192.168.1.110的数字+点的形式。这个选项已经过时了,虽然能用但不推荐。

-l 将日志记载到系统日志中。默认不记载到系统日志。

-b 允许在接口上进行广播,默认不广播。

-m mtu 设置接口的mtu值,用于覆盖axports中的paclen。

-v 显示版本信息。

参考阅读

kill(1), stty(1), ax25(4), axports(5), axparms(8), ifconfig(8).

作者

   Alan Cox GW4PTS <alan@cymru.net>
   Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>

2017年8月1日

实际试验

cat /usr/local/etc/ax25/axports 
#portname       callsign        speed   paclen  window  description
wl2k              BH2VJW          1200    255     4     Direwolf

sudo direwolf -p
sudo kissattach `ls -l /tmp/kisstnc | awk '{ print $11 }'` wl2k 10.89.1.123
AX.25 port wl2k bound to device ax0

ip a show ax0
31: ax0: <BROADCAST,UP,LOWER_UP> mtu 255 qdisc fq_codel state UNKNOWN group default qlen 10
    link/ax25 BH2VJW-0 brd QST-0 permaddr LINUX-1
    inet 10.89.1.123/8 brd 10.255.255.255 scope global ax0
       valid_lft forever preferred_lft forever

ping 10.89.1.123

主机的IP地址为10.89.1.122,给wl2k这个接口分配地址为10.89.1.123,此时从10.89.1.122 ping 10.89.1.123,Direwolf中会出现大量信息。

另外Direwolf文档声称kissattach对符号链接支持不佳,所以没有直接用 /tmp/kisstnc , 而是通过命令展开方式获取了设备实际地址。

linux-odroid内核没有预编译AX25模块,无法正常使用 kissattach 。主线内核预编译了这些模块,可惜与我的电视盒子兼容性不佳,无法正常重启,对于远程使用而言无法接受。于是只好自己编译内核了。

获取内核软件包并修改配置文件

git clone https://gitlab.manjaro.org/manjaro-arm/packages/core/linux-odroid.git
cd linux-odroid
vim config # 修改 # CONFIG_AX25 is not set

以下配置供参考:

1732 CONFIG_HAMRADIO=y
1733 
1734 #
1735 # Packet Radio protocols
1736 #
1737 CONFIG_AX25=m
1738 CONFIG_AX25_DAMA_SLAVE=y
1739 CONFIG_NETROM=m
1740 CONFIG_ROSE=m
1741 
1742 #
1743 # AX.25 network device drivers
1744 #
1745 CONFIG_MKISS=m
1746 CONFIG_6PACK=m
1747 CONFIG_BPQETHER=m
1748 CONFIG_BAYCOM_SER_FDX=m
1749 CONFIG_BAYCOM_SER_HDX=m
1750 CONFIG_YAM=m
1751 # end of AX.25 network device drivers

开始打包

makepkg --skipchecksums # 刚才修改了config文件所以无法通过校验,索性就不校验了
==> Making package: linux-odroid 5.18.12-1 (Fri 22 Jul 2022 10:10:46 AM CST)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Found 65a1da3b24ddcf7e4ddc52357d6f22d62ba441ad.tar.gz
  -> Found 0065-add-ugoos-device.patch
  -> Found config
  -> Found linux.preset
  -> Found 60-linux.hook
  -> Found 90-linux.hook
==> WARNING: Skipping verification of source file checksums.
==> Extracting sources...
  -> Extracting 65a1da3b24ddcf7e4ddc52357d6f22d62ba441ad.tar.gz with bsdtar
# 以下省略

2000 YEARS LATER

若干小时后编译还没有完成的迹象,还是找开发者吧 😂 已经私信了linux-odroid管理员,如果一切顺利linux-odroid 5.18.12即可支持AX25。

再更新

发现编译已完成,R3300-M四核马力全开足足跑了5个小时。编译完成前的输出如下:

==> Tidying install...
  -> Removing libtool files...
  -> Purging unwanted files...
  -> Removing static library files...
  -> Compressing man and info pages...
==> Checking for packaging issues...
==> Creating package "linux-odroid"...
  -> Generating .PKGINFO file...
  -> Generating .BUILDINFO file...
  -> Adding install file...
  -> Generating .MTREE file...
  -> Compressing package...
==> Starting package_linux-odroid-headers()...
Removing scripts/dtc/include-prefixes/openrisc
Removing scripts/dtc/include-prefixes/nios2
Removing scripts/dtc/include-prefixes/mips
Removing scripts/dtc/include-prefixes/arm64
Removing scripts/dtc/include-prefixes/microblaze
Removing scripts/dtc/include-prefixes/arm
Removing scripts/dtc/include-prefixes/arc
Removing scripts/dtc/include-prefixes/h8300
Removing scripts/dtc/include-prefixes/powerpc
Removing scripts/dtc/include-prefixes/sh
Removing scripts/dtc/include-prefixes/xtensa
==> Tidying install...
  -> Removing libtool files...
  -> Purging unwanted files...
  -> Removing static library files...
  -> Compressing man and info pages...
==> Checking for packaging issues...
==> Creating package "linux-odroid-headers"...
  -> Generating .PKGINFO file...
  -> Generating .BUILDINFO file...
  -> Generating .MTREE file...
  -> Compressing package...
==> Leaving fakeroot environment.
==> Finished making: linux-odroid 5.18.12-1 (Fri 22 Jul 2022 02:14:03 PM CST)
marly@manjaro-minimal  /linux-odroid   master   ls
Permissions Size User  Group Date Modified Name
drwxr-xr-x     - marly marly 21 Jul 20:42   .git
.rw-r--r--   241 marly marly 21 Jul 20:42   .gitlab-ci.yml
.rw-r--r--  4.3k marly marly 22 Jul 10:04   0065-add-ugoos-device.patch
.rw-r--r--   282 marly marly 21 Jul 20:42   60-linux.hook
.rw-r--r--  207M marly marly 22 Jul 10:04   65a1da3b24ddcf7e4ddc52357d6f22d62ba441ad.tar.gz
.rw-r--r--   229 marly marly 21 Jul 20:42   90-linux.hook
.rwxr-xr-x  228k marly marly 22 Jul  9:58   config
.rw-r--r--   68M marly marly 22 Jul 14:12   linux-odroid-5.18.12-1-aarch64.pkg.tar.zst
.rw-r--r--   12M marly marly 22 Jul 14:14   linux-odroid-headers-5.18.12-1-aarch64.pkg.tar.zst
.rw-r--r--   239 marly marly 21 Jul 20:42   linux-odroid.install
.rw-r--r--   234 marly marly 21 Jul 20:42   linux.preset
drwxr-xr-x     - marly marly 22 Jul 14:12   pkg
.rwxr-xr-x  7.0k marly marly 21 Jul 20:42   PKGBUILD
.rw-r--r--  2.1k marly marly 21 Jul 20:42   s912-dmip-mhz.patch
drwxr-xr-x     - marly marly 22 Jul 10:14   src

成功编译了内核和headers,运行 sudo pacman -U ./linux-odroid-5.18.12-1-aarch64.pkg.tar.zst ./linux-odroid-headers-5.18.12-1-aarch64.pkg.tar.zst 即可安装:

 marly@manjaro-minimal  /linux-odroid   master   sudo pacman -U ./linux-odroid-5.18.12-1-aarch64.pkg.tar.zst ./linux-odroid-headers-5.18.12-1-aarch64.pkg.tar.zst 
[sudo] password for marly: 
loading packages...
resolving dependencies...
looking for conflicting packages...
:: linux-odroid and linux are in conflict. Remove linux? [y/N] y

Packages (3) linux-5.18.11-1 [removal]  linux-odroid-5.18.12-1  linux-odroid-headers-5.18.12-1

Total Installed Size:  139.23 MiB
Net Upgrade Size:        9.91 MiB

:: Proceed with installation? [Y/n] y
(2/2) checking keys in keyring                                               [###########################################] 100%
(2/2) checking package integrity                                             [###########################################] 100%
(2/2) loading package files                                                  [###########################################] 100%
(2/2) checking for file conflicts                                            [###########################################] 100%
(3/3) checking available disk space                                          [###########################################] 100%
:: Processing package changes...
(1/1) removing linux                                                         [###########################################] 100%
(1/2) installing linux-odroid                                                [###########################################] 100%
Optional dependencies for linux-odroid
    crda: to set the correct wireless channels of your country [installed]
(2/2) upgrading linux-odroid-headers                                         [###########################################] 100%
:: Running post-transaction hooks...
(1/4) Arming ConditionNeedsUpdate...
(2/4) Updating module dependencies...
(3/4) Updating linux-odroid module dependencies...
(4/4) Updating linux-odroid initcpios...
==> Building image from preset: /etc/mkinitcpio.d/linux-odroid.preset: 'default'
  -> -k 5.18.12-1-MANJARO-ARM-ODROID -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img
==> Starting build: 5.18.12-1-MANJARO-ARM-ODROID
  -> Running build hook: [base]
  -> Running build hook: [udev]
  -> Running build hook: [plymouth]
  -> Running build hook: [autodetect]
  -> Running build hook: [modconf]
  -> Running build hook: [block]
  -> Running build hook: [filesystems]
  -> Running build hook: [keyboard]
  -> Running build hook: [fsck]
==> WARNING: No modules were added to the image. This is probably not what you want.
==> Creating gzip-compressed initcpio image: /boot/initramfs-linux.img
==> Image generation successful

至此编译安装内核成功完成,重启盒子继续折腾。

内核测试

uname -a
Linux manjaro-minimal 5.18.12-1-MANJARO-ARM-ODROID #1 SMP PREEMPT Fri Jul 22 10:17:23 CST 2022 aarch64 GNU/Linux

modinfo ax25
name:           ax25
filename:       (builtin)
alias:          net-pf-3
license:        GPL
file:           net/ax25/ax25
description:    The amateur radio AX.25 link layer protocol
author:         Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>

modinfo mkiss
name:           mkiss
filename:       (builtin)
alias:          tty-ldisc-5
license:        GPL
file:           drivers/net/hamradio/mkiss
description:    KISS driver for AX.25 over TTYs
author:         Ralf Baechle DL5RB <ralf@linux-mips.org>
parm:           crc_force:crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack] (int)


sudo direwolf -p

Dire Wolf DEVELOPMENT version 1.7 E (Jun 29 2022)
Includes optional support for:  cm108-ptt dns-sd
Dire Wolf requires only privileges available to ordinary users.
Running this as root is an unnecessary security risk.

Reading config file direwolf.conf
Audio device for both receive and transmit: plughw:0,0  (channel 0)
Channel 0: 1200 baud, AFSK 1200 & 2200 Hz, A+, 44100 sample rate.
Ready to accept AGW client application 0 on port 8000 ...
Ready to accept KISS TCP client application 0 on port 8001 ...
DNS-SD: Avahi: Failed to create Avahi client: Daemon not running
Virtual KISS TNC is available on /dev/pts/1
Created symlink /tmp/kisstnc -> /dev/pts/1


sudo kissattach /dev/pts/1 wl2k
AX.25 port wl2k bound to device ax0

测试结果符合预期。

经过一些阅读,比如Pt/Direwolf/SignaLink,Linux上的AX.25栈在过去的20年中没有得到良好维护,在2022年的可用性堪忧。这些问题暂且搁置,继续收集Linux实现Packet radio的拼图🧩碎片。

Pat是什么

Pat是一个跨平台的 Winlink 客户端,提供了命令行界面和网页界面

特点:

  • 收信发信(简单的信箱功能);
  • 自动压缩图片附件;
  • 可以通过GPS设备,网页定位或者手动输入方式报告位置消息;
  • 借助hamlib,可以为winmor PTT 和 QSY 提供电台控制;
  • 可以通过CRON风格的语法实现计划任务功能;
  • 内建了http服务器,提供了移动端友好的页面;
  • 提供了Git风格的命令行界面;
  • 支持同时以多种模式监听多条P2P连接;
  • 提供了 AX.25,telnet,WINMOR和ARDOP支持;
  • (试验性)消息可支持gzip压缩

Pat编译安装

编译平台:R3300-M,Manjaro ARM

git clone https://github.com/la5nta/pat
cd pat
./make.bash libax25
sudo ./make.bash

最后在当前目录下会生成一个名为pat的可执行文件,把它复制到/usr/local/bin就可以了。

Pat配置

首次执行后生成的配置文件为 $HOME/.config/pat/config.json ,结合实际修改。"http_addr": "localhost:8080" 可修改为 "http_addr": "0.0.0.0:8080" 以支持外部访问,否则只能在本机上打开网络页面。

Winlink账户貌似只能在 Winlink Express 客户端中注册,这个软件是免费的,运行于Windows系统。

Pat的网络页面提供了多样连接方式,在既无TNC又没有电台的情况下可以使用telnet连接,经测试连接正常。

Direwolf, AX.25, Pat

https://groups.io/g/direwolf/topic/use_pat_with_direwolf/80185118?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,0,40,80185118

参见Direwolf用户手册 5.8 Kiss TNC emulation-seial port (第25页)一节:

Direwolf可以扮演成一个使用Kiss协议、通过伪终端(pseudo terminal,设备路径形如/dev/pts/1)通信的传统TNC。通过伪终端可实现虚拟COM功能(所以之前设想的socat就不需要了):

编者按:伪终端(pseudo terminal)的应用很广泛。举个例子,通过SSH远程连接到Linux主机,在主机上便建立了一个伪终端。编号从0开始,由于建立了2个SSH连接,所以0和1便对应两个连接。(此时运行sudo direwolf -p,不出意外/tmp/kisstnc会指向/dev/pts/2)

who
marly    pts/0        2022-07-22 15:08 (10.89.1.253)
marly    pts/1        2022-07-22 15:08 (10.89.1.253)

ls /dev/pts
Permissions  Size User  Group Date Modified Name
crw--w----  136,0 marly tty   22 Jul 15:08   0
crw--w----  136,1 marly tty   22 Jul 15:11   1
c---------    5,2 root  root   1 Jan  1970   ptmx

Jeff, NC6J 于2021年1月分享的direwolf与Pat使用方式:

sudo direwolf -p 
# 观察pts符号链接,本例中假设为/dev/pts/1
sudo kissattach /dev/pts/1 port
# 这里的port是axports中定义的名称,对于Pat而言一般习惯用wl2k。我自编译的ax25apps,ax25tools,libax25不知为何没有将这些配置文件复制到指定位置。(axports复制到/usr/local/etc/ax25,自编译安装的kissattach在这里读取axports,而非 /etc/ax25)
pat http # 启动pat的网页页面
# direwolf -p 进程停止后,符号链接消失,kissattach结束

前言

硬件平台还是运行Manjaro ARM的R3300-M盒子,之前已经编译运行了direwolf,理论上连接各组件后即可使用。不过我的FT-8900R在车上,之前的试验中在车上给盒子供电的5V转12V升压线被烧掉了,所以一时半会儿还无法完成测试,可能加上1个12V直流稳压模块比较好。于是在这个“间隙”中,研究一下BBS系统的搭建。

BBS系统选择

之前连接到hb1bbs觉得还可以,这个BBS使用的是Mystic BBS系统。可惜经过测试,这个系统在Manjaro ARM上缺少 ld-linux.so.3 库文件所以无法运行。 AUR提供的 arm-linux-gnueabihf-glibc 可能提供了这个文件不过可惜这个包的依赖不支持arm64,好事者可以在X86-64电脑上安装然后提取。

迫于上述原因,我转而投向了 LinFBB

LinFBB安装

编译安装ax25

https://github.com/ve7fet/linuxax25 下载最新release然后编译。项目分三部分:ax25apps,ax25tools,libax25,分别进入目录执行

./autogen.sh
./configure
make -j4
sudo make install

编译过程大体上比较顺利。不过 ax25app 编译过程中会提示


call.c:45:10: fatal error: ncursesw/ncurses.h:No such file or directory
   45 | #include <ncursesw/ncurses.h>
      | 

开发者是基于Debian编译测试所以头文件名称与Manjaro有差异。按提示进入对应C文件将 #include <ncursesw/ncurses.h>修改为#include <ncurses.h>即可:

vim linuxax25-ax25tools-1.0.4/ax25apps/call/call.c #修改第45行

另外对于 ax25tools,安装后编译文件夹📁下面etc目录中的配置文件没有被复制到预期位置。比如执行

$ man axports

AXPORTS(5)                                       Linux Programmer's Manual                                       AXPORTS(5)

NAME
       /etc/ax25/axports - AX.25 port configuration file.

DESCRIPTION
……(以下省略)

在man文件描述的位置并没有这个配置文件,/usr/local 下面也没有。或许有必要手动创建/etc/ax25,然后把这些配置文件复制过去?

使libax25可被动态加载

cd /etc/ld.so.conf.d/
sudo vim userlocal.conf # 加入 /usr/local/lib 并保存
sudo ldconfig

这样刚才自编译安装的 libax25 就可以被动态加载了。一种比较古老的方式是使用 LD_LIBRARY_PATH 这个环境变量,不过Manjaro已经将其抛弃了,这个值默认是空的。

编译安装LinFBB

经过上面步骤后LinFBB编译安装水到渠成,照旧configure make make install三部曲,这个最后额外多了一步 make installconf

如果刚才没有安装配置好 libax25,这里在configure时会提示 configure: error: Could not find the libax25 libraries; aborting 导致编译无法进行。

另外需要指出,我的编译环境没有X11,所以不会编译xfbbx X11客户端。

LinFBB配置

上述编译安装步骤没有难度,从这里开始就要花一些心思了。

首次运行

sudo fbb

首次运行会提示许多文件不存在,按提示选择新建即可,然后添加呼号,姓名等必要信息。这些之后都可以在配置文件中修改,所以即便填错也没关系。

之后管理fbb应当使用 /usr/local/share/doc/fbb/fbb.sh这个脚本,用法如下:

fbb.sh start | stop | status | restart

等一切配置妥当后写一个systemd service用起来会更方便一点。

LinFBB提供了 xfbbdxfbbC 。先不研究它们,当前的目的是配置端口以便能够通过telnet访问这个BBS。

telnet配置

LinFBB虽然在持续的开发维护中,但BBS作为旧时代的遗珍,包括笔者在内的许多人对它很陌生。教人用wordpress之类东西搭建博客的教程浩如烟海,BBS的资料则只能散见于互联网的角落。 尽管搭建于上个世纪, https://www.f6fbb.org/ 仍然保留了大量价值无边的资料,可以作为配置LinFBB的指导。

此外 /home/manjaro/fbb-7.0.11/doc/html/ 目录中也提供了帮助文档,可以阅读。

参考页面: https://www.f6fbb.org/fbbdoc/fmttelne.htm
编辑PORT.SYS:


#Ports:端口数量
#TNCs:总共有几个TNC(调制解调器)。在使用多工器的情况下,一个端口最多可以有4个TNC。
#Ports TNCs
2      2

#COM:串口序号,注意与Windows中的COM1 COM2概念不同,此处仅作为序号。
#Interface:在LinFBB中仅有9一个可选项,代表Linux,可以用于串口、AX25域套接字、Telnet端口。
# Address:设备名/端口号。需要确保合适权限使LinFBB可以访问设备。此外,当使用 AF_AX25 内核端口时,地址是不需要的;当使用Telenet时,地址是Tenlet端口的16进制形式。
# Baud:端口的波特率。BPQ,AF_AX25内核套接字,以及Telnet无视该设定所以填0即可。
# 这一栏目的行数与上面的端口数量保持一致。(本例中为2)

#Com Interface Address (device)   Baud
1    9         /dev/cua0          9600
2    9         189C               0

# TNC:使用中的TNC数量。0代表文件转发。
# NbCh:TNC使用的频道数量,上限取决于TNC固件。(编者注:对于direwolf之类soundcard modem,是否意味着一个TNC只有一个Channel?)
# Com:COM口的序号,需要与前文保持一致。
# MultCh:使用端口多工器情况下的频道数量,否则为1。对于DRSI用途,值为0~7;by KAM use 1/VHF and 2/HF;Linux中使用AF_AX25内核套接字时,MultCh为接口名称(例如:ax0)
# Paclen:TNC的Paclen(这是啥)
# Maxfr:TNC最大可以同时发送的帧数
# NbFwd:最多同时向外发送的频道数量。
# MaxBloc:forward-block的大小,单位为kb。
# M/P-Fwd:M代表每小时中开始转发的起始分钟,P-Fwd代表每次转发开始之间的时间间隔
# Mode:单个字母的组合,每个字母代表一种允许的模式,太长了不翻。以TUWR为例,T代表Ethernet/TCP-IP(host-mode),U代表正常模式(Port mode),W代表网关允许这个频率(附加内容),R代表调制解调器端口允许只读模式(附加内容)
# Freq:用于描述这个端口的字符串,长度最大为9,不允许空格(编者注:用Comment是不是更直观一点)

#TNC NbCh Com MultCh Pacln Maxfr NbFwd MxBloc M/P-Fwd Mode Freq
0    0    0   0      0     0     0     0      00/01   ----  File-fwd.
1    4    1   1      230   4     1     10     30/60   UDYL  433.650
2    8    2   0      250   2     1     10     00/60   TUWR  Telnet

本例中,telnet端口号为6300,转换为16进制即为 189C。重启fbb,通过nmap可以看到本机6300端口已打开,局域网中其他设备也可以通过telnet访问BBS。虽然我们的TNC尚未配置好,**/dev/cua0** 也不存在,不过不影响Telnet端口的使用。

(编者补充:在linux中,com设备一般被命名为cua)

AX.25探究

fbb-7.0.11/doc/html/tllinux.htm 成文时间久远(1997),许多内容已经过时。不过其提及的AX25-HOWTO(成稿于2001年九月)值得阅读。如果上面链接不幸死掉了,可以访问 https://tldp.org/HOWTO/AX25-HOWTO/

加载AX25内核模块

这一部分不太乐观。简单检查了一下Manjaro系统(21.3.3)的内核模块,以下是默认具备的:

  • ax25
  • netrom
  • rose
  • slip
  • mkiss
  • lp
  • baycom_par baycom_ser_fdx baycom_ser_hdx

关键的soundmodem(sm0)不在其中。https://github.com/VK3FNG/soundmodem 显示这个模块代码已经被开发者放弃。

  1. 编译安装linuxax25-ax25tools-1.0.4其中的三个模块。上文中已完成。
  2. 执行 sudo modporbe ax25

编者按:ax25这个模块貌似是系统自带的,**/lib/modules/5.16.20-2-MANJARO/kernel/net/ax25/ax25.ko.xz** 的创建时间远远早于编译时间。

如果需要系统启动时自动加载这个模块,可以利用 /etc/modules-load.d 实现,具体参见 man modules-load.d

整合Direwolf

参考XRpi interfacing with LinFBB 一文,作者使用 socat 创建了虚拟COM口供 XRouterLinFBB 使用。Linux中万物皆文件,所以使用socat创造的虚拟COM口也是一个文件,将这个文件提供给XRouterLinFBB的配置文件,让它们都使用这个虚拟COM口,就实现了利用虚拟COM口连接XRouterLinFBB 的目的。

Direwolf手册中描述了利用 com0com 创建虚拟COM接口以及修改Direwolf的步骤,可以作为参考。

未完待续

KB1OIQ - Andy’s Ham Radio Linux

项目地址: https://sourceforge.net/projects/kb1oiq-andysham/

一个被KB10IQ积极维护的Linux发行版,基于Xubuntu 22.04.0,最近更新于2022年6月14日。主要包含以下特性:

  • Live medium which can be installed to the hard drive or USB thumb drive
  • Xfce4 desktop environment
  • Contains a large number of amateur radio programs
  • Amateur Radio menu customized for ease of use
  • Nothing proprietary (as far as I know)
  • Software came from the Ubuntu repositories, PPAs, and source tar files
  • Software defined radio receiver with RTL2832 USB dongle
  • Micro-Fox Config GPL and TinyTrak3 Config GPL
  • GNU Radio Companion and gqrx
  • FreeDV (free digital voice)
  • Packet radio software linpac and AX25
  • pskmail client and server
  • digital radio mondiale
  • Learn CW via the Wordsworth method
  • FT8 via wsjt-x
  • js8call
  • Arduino IDE and libraries, plus Fritzing
  • nanoVNA and tinySA software
  • Don’t forget to install GridTracker! See HOWTO_GridTracker document.
  • SDRangel

Packet Radio是我所需要的,其他人可能对FT8更感兴趣。系统支持Live USB,方便使用体验。

DragonOS_Focal

emaxecuter专门为SDR打造的Linux发行版,基于Lubuntu 20.04,最近更新于2022年5月21日。主要包含以下特性:

  • Acarsdec w/ rtlsdr support
  • Aircrack-ng 1.6
  • Airspy_ADSB
  • Apache2
  • Asterisk
  • Auto137
  • BladeRF ADSB w/ Dump1090 Mutability (/usr/src)
  • BladeRF-Wiphy (usr/src/wiphy-build)
  • Blue hydra
  • Boatbod op25
  • BTLE w/ hackrf (can be recompiled for bladeRF)
  • CalypsoBTS w/ firmware + tools
  • Cesium
  • Chirp-daily (python2)
  • Composable-SDR AppImage with SDRPlay support (/usr/src/Soapy_SDR-x86_64)
  • Crocodile Hunter (LimeSDR Mini support)
  • CubicSDR
  • DF-Aggregator w/ Offline capability
  • Direwolf
  • Dumphfdl
  • DumpVDL2
  • Esptool
  • FALCON
  • Fldigi
  • GNU Radio 3.8
  • Gpredict
  • GQRX
  • GQRX Scanner
  • GR-ADSB
  • GR-AIR-Modes
  • GR-AOA
  • GR-Correctiq
  • GR-DECT2
  • GR-DSD
  • GR-FHSS_Utils
  • GR-Foo
  • GR-Grnet
  • GR-GSM
  • GR-ieee802-11 w/ HackRF Sink TX Flowgraph
  • GR-ieee802-15-4
  • GR-IIO
  • Gr-Inspector (/usr/src)
  • GR-Iridium
  • GR-limesdr
  • GR-Lora
  • GR-Lora_SDR
  • GR-Mixalot
  • GR-NFC
  • GR-NRSC5
  • GR-NTSC-RC
  • GR-Paint38
  • GR-PDU_Utils
  • GR-RDS
  • GR-Sandia_Utils
  • GR-Satellites
  • GR-Smart_Meters
  • GR-Soapy
  • GR-Tempest
  • GR-Timing_Utils
  • Grgsm_scanner-GUI
  • GSMEvil2
  • HackTV GUI v2021-11-09
  • Ham2Mon by lordmorgul
  • IceCast2 (needs configured before starting)
  • IMSI-catcher
  • Inotify-tools
  • Inspectrum 0.2.3
  • Iridium-Toolkit
  • IridiumLive
  • JAERO
  • Js8call
  • JTDX
  • Kalibrate (HackRF)
  • Kismet
  • Kismet rest api
  • Kisstatic2mobile w/ latest kismet support
  • Kismon
  • Larry Tetra Kit e9f93618
  • LeanSDR/LeanDVB
  • Libacars
  • LibBladeRF 2.4.1 w/ xA5 support
  • LibhackRF/hackRF tools 2021.03.1
  • Libosmo-dsp
  • LimeSuite
  • Linrad
  • LiquidSoap
  • LTE-Cell-Scanner (v2 remains and supports RTLSDR, HackRF, BladeRF with CMake options)
  • LuaRadio v0.10.0 w/ examples
  • M17-Gnuradio
  • Meshtastic Python API 1.2.58(standalone)
  • Mirage (GitHub.com/RCayre/mirage
  • )
  • MMDVM
  • Mmdvm-sdr by r4d10n
  • MMDVMHost by g4klx
  • Multimon-ng
  • Nmap
  • NOAA-Apt 1.3.1
  • NRSC5 decoder for RTLSDR
  • Nzyme
  • OP25 “Boatbod” (GNU Radio 3.8/Python3 testing /usr/src/op25/)
  • OpenWebRX 0.20.3
  • Osmo-bsc
  • Osmo-bts-trx
  • Osmo-hlr
  • Osmo-MGW
  • Osmo-msc
  • Osmo-NITB
  • Osmo-nitb-scripts (@NotPike)
  • Osmo-Sip-Connector
  • Osmo-trx-lms (LimeSDR support)
  • Osmo-trx-uhd
  • Osmocom-BB tools in /usr/src
  • Photonmap
  • Probequest
  • Pyadi-iio
  • PyRtlSDR
  • PySDR 2.0 (Guide to SDR and DSP using Python)
  • Qalculate
  • Qfits for use with sattools
  • QradioLink w/ MMDVM ability
  • QspectrumAnalyzer
  • Qsstv
  • Qt-DAB
  • RDF-Sim
  • Retrogram-RTLSDR
  • Retrogram-soapysdr
  • Reveng
  • RFcat
  • RFCrack
  • RFsoapyfile
  • RMSViewer
  • RSP TCP Server (SDRPlay support)
  • RTL_433
  • RTLSDR-Airband v4.0.1 (conf in /usr/src/)
  • RX_Tools
  • SatDump
  • SDR++ w/ server capability
  • SDR4space.lite w/ examples
  • SDRAngel
  • SDRReceiver
  • SDRTrunk
  • ShinySDR
  • SigDigger
  • Signal Server GUI w/ python3 virtual environment
  • Signal Server N90ZB w/ Web Interface by Dr. Bill Walker
  • Soapysdr modules
  • Sparrow-WiFi w/ FALCON tools + wpapcap2john
  • Splat!
  • SpyServer (usr/src/spyserver-linux-x64)
  • srsLTE-Sniffer (loop-catcher.sh in /usr/src/srsLTE-release_18_12/build/lib/examples)
  • srsRAN
  • Strf
  • Tetra-kit “screen2tetra.sh” script in /usr/src/tetra-kit/recorder/wav
  • Tetra-Kit-Player in /usr/src (needs npm installed)
  • Trunk-Recorder
  • Ubertooth 2020-12-R1
  • Umurmur
  • Universal Radio Hacker
  • WFView from source
  • wireguard
  • Wireshark
  • WSJT-X
  • Yate/YateBTS w/ BladeRF xA4 improvements
  • yellowShoes nrsc5 HD FM audio player
  • Zenmap

包含了先前提到的Direwolf。

前言

一直想体验下packet radio,不过国内错过了packet radio最流行的年代,所以硬件TNC也淘不到,大家都一步跨进了声卡时代,用 soundcard modem 作为关键词可以搜索到很多。基于此,尝试用手边的廉价配件拼凑出一台可用的TNC,用作packet radio之途。

所谓的soundcard modem,简单而言利用声卡的DSP(Digital Signal Processing)功能,实现数模转换。以AFSK为例,定义了2个不同声调分别代表0和1,实现数传功能。硬件方面需要一部具备声卡的计算机,软件方面需要特定程序实现调制解调以及PTT控制功能。伴随着思路逐渐清晰,整个系统的组件大致如下:

组件

  1. 计算机
    还是老朋友R3300-M :P 安装运行Manjaro ARM minimal。我打算把它当成网络TNC,通过网络用其他电脑远程连接使用。如果需要本地使用也可以运行sway之类图形系统,配置应该不成问题。
  2. 声卡
    几块钱包邮的USB声卡。
  3. 电台连接器
    这个是整套系统中最有难度抑或最花钱的部分。成品难找而且价格普遍不菲,DIY需要专业知识以及动手能力。
  4. 电台
    电台要求很低,最廉价的FM收发机即可,当然要结合电台连接器。
  5. TNC 软件
    使用Dire Wolf。这个软件的功能比较多,对于我的用途而言使用KISS协议作为一个远程TNC即可。

    实现

  6. 在R3300-M上运行Dire Wolf。毫无难度,按说明编译运行即可。
  7. 声卡配置。USB声卡即插即用,为方便配置可以安装 alsa-utils,这个包提供了 alsamixer ,可以比较直观地对音频进行配置。
  8. 电台连接器。从马工淘宝店250块钱买的。
  9. 电台。FT-8900R。其实更想用UV-5R,不过国内没找到连接器,国外论坛有人分享电路图,有心人自己去看吧。电台的波特率设置为1200bps。
  10. 路由器。闲鱼15块钱收的必虎无线路由器。5V DC供电,1 WAN 2 LAN,刷了openwrt后用来连接R3300-M很合适。
  11. 终端电脑。华硕EEE 1025CE。渣配上网本,特意为它更换了SSD,又淘来了一枚100W PD诱骗头,这样可以在汽车上搭配小米100W充电器使用,达到全直流供电目的,与整套车载供电与太阳能发电系统形成整体。

整套系统依托汽车搭建。调试成功后,在无线路由器覆盖范围内,都可以方便地用笔记本进行Packet Radio操作。

进度

已完成

  1. 所有必备硬件已准备完毕。
  2. Dire Wolf编译完毕,可正常运行。
  3. 必虎路由器刷机完毕。

    计划中

  4. 安装合适的Packet Radio终端软件。
  5. 连接系统各硬件模块。
  6. 参照手册对Dire Wolf进行配置。

原本用于编译openwrt的Deepin在一次升级中挂掉了,于是尝试在Manjaro下编译。

sudo pacman -S base-devel asciidoc binutils bzip2 gawk gettext git ncurses zlib patch unzip lib32-glibc subversion flex gcc-multilib p7zip msmtp lib32-openssl texinfo xmlto qemu upx libelf autoconf automake libtool gettext

比ubuntu下的依赖项少了一些,不过用默认配置跑了一遍正常生成镜像。

7月11日更新

由于众所周知的原因golang在编译时会提示 dial tcp 172.217.160.113:443: i/o timeout 并导致编译失败。可以通过使用代理解决:

export GO111MODULE=on
export GOPROXY=https://goproxy.cn
make download -j8
make -j2 V=s

如此之后顺利编译:

ls lede/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/tmp/

openwrt-ramips-mt76x8-glinet_vixmini-initramfs-kernel.bin
openwrt-ramips-mt76x8-glinet_vixmini-squashfs-sysupgrade.bin
openwrt-ramips-mt76x8-glinet_vixmini-squashfs-sysupgrade.bin.sig
openwrt-ramips-mt76x8-glinet_vixmini-squashfs-sysupgrade.bin.ucert

sudo pacman -S texlive-most texlive-langchinese

manjaro软件仓库里的 texlive 比较精简,没有附带宏包手册所以 texdoc 不能用, latex 初学者还是建议去CTAN下载完整镜像手动安装。我是为了编译之前写好的文件所以没有手册影响不大。(原本写作环境Deepin挂掉了)