With some time over the holidays I have been working on the Pacsat Ground station. It had an issue uploading longer files. Short files generally uploaded well, but longer files never seemed to complete.
I diagnosed the issue watching an image file try to upload. It would upload the whole image and then we get this packet:
From:PFS3-12 to AC2CZ Ctrl: e4 Type: I Cmd PF: 0 NR: 7 NS: 2 1 7 10> UL NAK 16: ER_BODY_CHECK
That error is sent from the spacecraft when the DATA_END packet is sent from the ground station. It means that the checksum in the Pacsat File Header does not match the checksum calculated for the body of the file. The file is corrupt (or, unlikely, the checksum in the header is wrong). The error is not treated as fatal by the ground station as there can very occasionally be corruptions in the channel, so we ask for a new File ID and try to upload the file again. But this then repeats over and over. Uh oh. We are stuck in a loop consuming lots of bandwidth to the spacecraft and not getting anywhere.
So I dug a bit deeper and saw this in the log (slightly edited here to make it shorter):
From:PFS3-12 to AC2CZ Ctrl: e1 Type: S Res PF: 0 NR: 7 SS: RR
From:AC2CZ to PFS3-12 Ctrl: 4e Type: I Cmd PF: 0 NR: 2 NS: 7 fe 0 31 8e 18 8e c0 c7 ( ... plus 250 other bytes)
Connected: T1 expired
Timer Rec: Adding Frame: From:PFS3-12 to AC2CZ Ctrl: f1 Type: S Res PF: 1 NR: 7 SS: RR
From:PFS3-12 to AC2CZ Ctrl: f1 Type: S Res PF: 1 NR: 7 SS: RR
Timer Rec: BACKTRACK: VS: 0 - NR:7
Connected: SENDING: From:AC2CZ to PFS3-12 Ctrl: 4e Type: I Cmd PF: 0 NR: 2 NS: 7 8 3 0 0 0 0 c4 c3 0 0.......... ...
So in the log above we get an S frame of type RR confirming our previous iframe with NR = 7. This means the spacecraft confirms our frame sent wioth NS 6 and is now expecting our frame with NS set to 7. So we send another 256 data bytes with NS = 7. But then timer T1 expires We did not hear the response from the spacecraft. This is normal. The whole process is expected to continue with a connection that fades and peaks. So we send an S frame of type RR with P set to 1 to poll the spacecraft. It responds with an S frame of type RR and NR still set to 7 and with P set to 1, which is effectively asking for our iframe numbered NS 7 to be sent again. We are in the "Timer Recovery" state of the AX25 Data State Machine. So asking for NS 7 again when we were about to send NS 0 causes us to back track. This is all normal behavior in a noisy channel, but then we see a real error. We resend the frame with NS = 7, but it is not the same frame as before. It starts with bytes 8 3 0 0 rather than fe 0 31 83. It is an older frame. Something has gone wrong in the logic.
So with that clue I debugged the logic where we resend frames and found a bug in the way it backtracks.
With the bug hopefully fixed I tried to upload a 50k image file. In the first pass it uploaded 15k. The next pass, frustratingly, I did not hear the spacecraft at all despite it being a 31 degree pass. Mark N8MH suggested that sometimes the spacecraft blocks its own antennas. They can be behind the spacecraft from your perspective. So I waited. On the third pass it connected and uploaded nearly the whole file without issue, but then reception was poor and I timed out. When it reconnected the final bytes were uploaded and I saw the magic lines in the log shown below. The 2 bytes from me are the DATA END packet followed by acceptance of the file by the spacecraft with the UL_ACK_RESP code:
From:AC2CZ to PFS3-12 Ctrl: 40 Type: I Cmd PF: 0 NR: 2 NS: 0 2 data byte(s) ...
From:PFS3-12 to AC2CZ Ctrl: 24 Type: I Cmd PF: 0 NR: 1 NS: 2 > PID:f0 UL_ACK_RESP
An additional challenge was that tracking the upload was difficult, so I added a simple indicator to the GUI of the file that is being uploaded and the progress through the file. This could be a lot nicer, but right now any indication is helpful. If debugging is on that that information is also written to the log for every chunk uploaded.
One other feature that was missing from the ground station was support for compressed files, so this was also added into version 0.36. This is important for a data link that only operates at 9600 bps. I wanted the support to be much easier than with WISP, so I decided to only support one type of compression and to use the built in support for ZIP files that Java has. I implemented it so that compressed files are transparently decompressed and displayed in the editor. If the user ticks "Compressed", as you can see in the editor window at the start of this post, then the pacsat file is compressed before it is saved and sent. You can even go back into a file in the upload queue, click Compressed after the fact and then hit send again. Of course that does not make much difference for a JPG as it is already compressed but it makes a big difference for a text file which can shrink to half its size.
I added a "Zip" column to the directory to track which files are compressed, mainly for debugging. In daily use you should not care. In fact I would like to propose that all files should be compressed to save bandwidth.
I tested by sending and receiving a message from Andrew G8TZJ who is using WISP. Everything seems to work well.
I have also added support for messages that contain a text and image file. I see that combination from WISP sometimes. Currently you can not create that type of file in the Pacsat Ground Station, but you can display them fine.
If other types of compressed files are received then you can always Export the user file to disk and cope with it yourself in Windows. In fact that should always work with any type of file. Unlike WISP there is no automatic mode to extract other types of files.
If you want you can find the download for PacSatGround Version 0.36 or see other blog posts and thoughts about the software.
73
Chris
g0kla/ac2Cz
Enter Comments Here:
Copyright 2001-2021 Chris Thompson
Send me an email