wb2osz / direwolf

Dire Wolf is a software "soundcard" AX.25 packet modem/TNC and APRS encoder/decoder. It can be used stand-alone to observe APRS traffic, as a tracker, digipeater, APRStt gateway, or Internet Gateway (IGate). For more information, look at the bottom 1/4 of this page and in https://github.com/wb2osz/direwolf/blob/dev/doc/README.md
GNU General Public License v2.0
1.6k stars 306 forks source link

Invalid Transmit Channel #42

Closed dhchenault closed 4 years ago

dhchenault commented 8 years ago

I am running Dire Wolf in Jessie on a RPi. Works great. I'm using it with packlink as well as simply connecting with axcall.

However, when it initially starts up, the first two transmit attempts result in "Invalid Transmit Channel" errors. The third transmit attempt always works and then all subsequent attempts work.

What am I doing wrong?

Thanks, David

image

dranch commented 8 years ago

Hello David,

What version of Direwolf are you using here? Did you compile it yourself or did someone send you the binaries? Can you cite the commands you're using to start up Direwolf and connect it to Linux's AX25 stack?

--David KI6ZHD

dhchenault commented 8 years ago

Running ver 1.2. Compiled it myself following tutorial here: https://andrewmemory.wordpress.com/2015/03/22/setting-up-direwolfxastir-on-a-raspberry-pi/

I'm running is with the KISS port inside an lxterminal lxterminal -e direwolf -p Then attaching to my "radio" port setup in ax25 sudo kissattach /tmp/kisstnc radio 44.56.4.120

Thanks, David, W5CWT

dranch commented 8 years ago

Hello David, Few thoughts... I would first upgrade to Direwolf 1.3 as there are a lot of improvements there. Next, try using parts of the follow startup script and see if things work better for you: http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/ax25/ax25-up.new --David

wb2osz commented 8 years ago

Let’s look at the KISS data from the client application.

The first byte is a channel number in the upper 4 bits and a command in the lower 4 bits.

In the first case, “80” means transmit on channel 8.

In the second case, “20” means transmit on channel 2.

Dire Wolf appears to be acting correctly. The application is asking for transmission on channels 8 and 2.

I ran into something like this before. Look in source file kiss_frame.c, around line 471, for the comment about “special hack.”

I think there is a bug in the AX.25 for Linux code where it tries to transmit on channels 2 and 8. I put in a special hack to discard the one case I ran into.

MikePlayle commented 5 years ago

I came across this the other day with Xastir, and took a quick look. The problem is fixable without the kiss_frame.c hack, which doesn't help with Xastir anyway.

I had a little while to write it up while I wait for the oven. Merry Christmas!

Workaround

After the kissattach command, put the interface into CRC mode "none" with a command like this:

# kissparms -c 1 -p radio

Analysis

The source of this behaviour is the kernel's KISS implementation:

https://elixir.bootlin.com/linux/v4.9/source/drivers/net/hamradio/mkiss.c#L489

It defaults to starting in state CRC_MODE_SMACK_TEST and ending up in state CRC_NONE after the first two packets, which have their framing byte modified by this code in the process. It looks to me like deliberate behaviour on the kernel's part.

Setting the CRC mode explicitly before sending any packets stops this state machine from running.

Is this a bug? I don't know - that's up to you! Maybe it would make sense for Direwolf to set the CRC mode itself, or to expect this behaviour and ignore these flags on the first packets received from the Linux pty.

This workaround seems sound to me, though, so perhaps this is just a documentation issue.

wb2osz commented 4 years ago

Direwolf works correctly. The solution is to add the "-c 1" option to kissparms command.

dranch commented 4 years ago

Another way of doing this is pre-loading the "kiss" kernel module with CRC disabled:

sudo /sbin/modprobe -q mkiss crc_force=1

cb3rob commented 2 years ago

i would say it's a bug if it uses 'production' packets the user sent for some silly protocol negotiation test. yes. also ran into it and yes the kiss control byte is modified by the kernel itself in the first 2 packets sent over a freshy created pty/tty (indeed to $80 on the first and $20 on the second packet) with line dicipline N_KISS. if it want's some settings for some options just add an ioctl for it. not entirely sure how a tnc would ever return an error to this 'test' anyway seing that tnc's are not really supposed to send any data back on their own behalf. ever. think i'll just 'fix' it in our kiss-tnc-attach by forcing the channel to 0. but pty's are not guaranteed to return one whole packet per read() (neither is tcp, and least of all actual rs232) so then we'd have to move the kiss frame collection and parsing to the attacher too (although so far i haven't seen a single read() that wans't one whole packet... the thing still is in non-blocking mode with a raw pty and on all those other million packets but the first 2 it'd cause additional cpu cycles. ;) better just fix the kernel. (or just hook your kiss-tcp attacher to a tap+bpq device instead and encode/decode kiss in userspace (problem there is that you can't find the corresponding bpq device name without searching through that proc file. it lacks an ioctl. you also can't change the encapsulation on the tap device to arphrd_ax25 directly. well you can. but it'll bug on 7 byte hwaddrs... tap thinks the whole world is ethernet. ;)

cb3rob commented 2 years ago

socket(AF_PACKET, SOCK_PACKET, 512) = 3 sendto(3, "\x85\x01", 2, 0, {sa_family=AF_UNSPEC, sa_data="\x61\x78\x30\x00\x00\x00\x26\xb0\x62\x65\x00\x00\x00\x00"}, 16) = 2

hmm. that seems to be the 'operational part' of 'kissparms -c 1 -p ax0' .. let's see what the 'nicely written form' in it's source code is and IF it actually works ;) can't quite see what sending a raw packet with $85 $01 payload to 'ax0' (the old PF_PACKET,SOCK_PACKET,512 has sockaddr_pkt instead lf sockaddr_ll indeed (basically just the asciiz device name (and shorter than IFNAMSIZ at that - it's old for a reason ;) anyway if kissparms can do it then so can the actual program opening ax0 ;)

wb2osz commented 2 years ago

There is a well documented work-around:

After the kissattach command, put the interface into CRC mode "none" with a command like this:

kissparms -c 1 -p radio

It would be great if the AX.25 for Linux maintainers would make this the default behavior.

cb3rob commented 2 years ago

fixed in the same way kissparms does it. including the use of antique SOCK_PACKET now, indeed, the first 2 packets arrive fine too.

https://github.com/cb3rob/CB3ROB-AX25-TOOLS-LINUX/blob/main/cb3rob-kiss-tcp-attach.c

cb3rob commented 2 years ago

thing is we don't believe in those silly old axtools that require a seperate /etc/ax25/axports thing. and that includes kissparams :P plus it should indeed be the default setting. also the normal way of changing settings is by ioctl with an ifreq .. not by sending some raw bytes to a sniffer socket.. lol. also any and all documentation on anything is severely lacking.