Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with Terms in Output? #2

Closed
K4KDR opened this issue Mar 28, 2022 · 6 comments
Closed

Help with Terms in Output? #2

K4KDR opened this issue Mar 28, 2022 · 6 comments

Comments

@K4KDR
Copy link
Contributor

K4KDR commented Mar 28, 2022

After registration & download of the Public Key, I have used the 'nc' method to see the processing myself.

I understand a portion of what is occurring, but could I ask for some clarification, please?

Could you please expand on what is meant by "word", as in "received word 6 from E14 doesn't match word stored for the same subframe"

Also, in this context, what exactly is a "subframe"?

Finally, would this output be more understandable if viewed using env_logger? (if so, command syntax appreciated)

Thank you!

-Scott, K4KDR

[local output used as the basis for my questions:]

k4kdr@3010i5:~/galileo-osnma/galmon-osnma$ nc 86.82.68.237 10000 | RUST_LOG=info cargo run --release OSNMA_PublicKey_20210920133026.pem
   Compiling galileo-osnma v0.1.0 (/home/k4kdr/galileo-osnma)
   Compiling galmon-osnma v0.1.0 (/home/k4kdr/galileo-osnma/galmon-osnma)
    Finished release [optimized] target(s) in 5.88s
     Running `target/release/galmon-osnma OSNMA_PublicKey_20210920133026.pem`
[2022-03-28T15:20:38Z INFO  galileo_osnma::subframe] starting collection of new subframe (GST Gst { wn: 1179, tow: 141645 })
[2022-03-28T15:20:48Z INFO  galileo_osnma::subframe] starting collection of new subframe (GST Gst { wn: 1179, tow: 141661 })
[2022-03-28T15:21:11Z WARN  galileo_osnma::navmessage] received word 6 from E04 doesn't match word stored for the same subframe(received = BitSlice<u8, bitvec::order::Msb0> { addr: 0x56286dfa48a0, head: 110, bits: 119 } [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0], stored = BitSlice<u8, bitvec::order::Msb0> { addr: 0x7fff0e554e78, head: 000, bits: 119 } [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
[2022-03-28T15:21:12Z WARN  galileo_osnma::navmessage] received word 6 from E33 doesn't match word stored for the same subframe(received = BitSlice<u8, bitvec::order::Msb0> { addr: 0x56286dfa48a0, head: 110, bits: 119 } [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0], stored = BitSlice<u8, bitvec::order::Msb0> { addr: 0x7fff0e554e78, head: 000, bits: 119 } [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]

///// cut /////

[2022-03-28T15:21:17Z INFO  galileo_osnma::dsm] new DSM id = 7 (had id = 0). resetting
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:17Z INFO  galileo_osnma::osnma] no valid TESLA key yet. unable to validate MACK key
[2022-03-28T15:21:18Z INFO  galileo_osnma::dsm] completed DSM with id = 7, size = 104 bytes
[2022-03-28T15:21:18Z INFO  galileo_osnma::osnma] verified KROOT

[2022-03-28T15:21:18Z INFO  galileo_osnma::osnma] initializing TESLA key to Key { data: [229, 127, 156, 108, 96, 45, 248, 171, 161, 98, 187, 109, 194, 103, 204, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], chain: Chain { status: Test, id: 1, hash_function: Sha256, mac_function: HmacSha256, key_size_bytes: 16, tag_size_bits: 40, maclt: 33, alpha: 41590689997730 }, gst_subframe: Gst { wn: 1179, tow: 136770 }, _validated: Validated }

[2022-03-28T15:21:18Z INFO  galileo_osnma::osnma] new TESLA key Key { data: [217, 202, 234, 204, 29, 131, 246, 78, 1, 80, 37, 43, 249, 168, 197, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], chain: Chain { status: Test, id: 1, hash_function: Sha256, mac_function: HmacSha256, key_size_bytes: 16, tag_size_bits: 40, maclt: 33, alpha: 41590689997730 }, gst_subframe: Gst { wn: 1179, tow: 141660 }, _validated: Validated } successfully validated by Key { data: [229, 127, 156, 108, 96, 45, 248, 171, 161, 98, 187, 109, 194, 103, 204, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], chain: Chain { status: Test, id: 1, hash_function: Sha256, mac_function: HmacSha256, key_size_bytes: 16, tag_size_bits: 40, maclt: 33, alpha: 41590689997730 }, gst_subframe: Gst { wn: 1179, tow: 136770 }, _validated: Validated }
[2022-03-28T15:21:18Z INFO  galileo_osnma::subframe] starting collection of new subframe (GST Gst { wn: 1179, tow: 141691 })
[2022-03-28T15:21:42Z WARN  galileo_osnma::navmessage] received word 6 from E14 doesn't match word stored for the same subframe(received = BitSlice<u8, bitvec::order::Msb0> { addr: 0x56286dfa1b10, head: 110, bits: 119 } [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0], stored = BitSlice<u8, bitvec::order::Msb0> { addr: 0x7fff0e554ddc, head: 000, bits: 119 } [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1]

///// cut /////


@daniestevez
Copy link
Owner

Hi Scott,

Words and subframes are how the Galileo navigation message is organized. You can read up all the details in the ICD, especially in Section 4.3. A word is basically the smallest unit of information that is sent. Think a packet. One word is sent every 2 seconds. They have a numbers or types, which indicate what kind of data they contain. For instance, these two:

words

Now, to get all the information, you must collect one word of each type (just because each type holds a different piece of the complete data). So words are organized in a subframe of 15 words (which takes 30 seconds to transmit). These 15 words are essentially (this is not 100% accurate) one of each type, so by receiving the 15 words you get hold of the whole data. The subframe starts like this, and the same structure repeats every 30 seconds (you can just look at the E1B column and ignore the slightly confusing boxes with "Res", "Spare", "CRC", and so on).

subframe

For OSNMA, the receiver is supposed to collect some of the words from one subframe (not all the data is authenticated, so only some words play a role in OSNMA), and then check that data against the signature (tags) that is transmitted in the next subframe.

The sentence

received word 6 from E14 doesn't match word stored for the same subframe

is actually quite interesting. There are two classes of data authenticated by OSNMA. One is the satellite ephemerides (its orbital parameters). This data is specific per satellite. The other one is the Galileo constellation timing information (the difference between Galileo time, GPS time and UTC, leap seconds, and that stuff). This data is "global" for all the satellites. So you should be able to put together the timing information that you receive from any of the satellites to get a complete copy. Keep in mind that the receiver might have to discard some words due to bad CRC if the signal is not good. So having multiple chances to get the same piece of data helps.

Word 6 is one of these constellation timing information words. But what happens in practice is that not all the satellites are sending exactly the same information. They are sending close enough values, but not the same. Maybe some satellites got an updated copy of the data earlier than the others or whatever. Before OSNMA came, this used to be only slightly annoying. In the end it doesn't matter what of the two versions of the information you use, because the values are close enough. However, with OSNMA it does matter, because even if the data is close enough, the cryptographic signatures will be completely different.

So what's happening is that galileo-osnma (the Rust library) is seeing this conflicting information and giving a warning. When it sees this, it keeps the first version of the data it received (in that particular subframe). But that version of the data may or may not match the signature (you may see some errors regarding tag authentication for timing parameters because of this). I am not quite sure how receivers are supposed to handle this, but it is quite inconvenient.

Regarding env_logger, you're already using it. env_logger is a Rust library that generates the log that you're seeing as output. It lets you control what kind of data you want to see by setting the RUST_LOG environment variable. So, for instance, if you set RUST_LOG=galileo_osnma::subframe=trace, then you'll see very detailed information about the module that processes the subframes and nothing else from the rest. You can specify a different detail of logging (logging level) for each module if you want. The documentation of env_logger gives some examples that show how to do that.

@K4KDR
Copy link
Contributor Author

K4KDR commented Mar 28, 2022

Regarding env_logger, you're already using it

Ah, very good. I thought the reference to that utility was beyond what was being displayed... i.e., a completely different tool. Thank you for the clarification!

Because there are so many of those "received word ... doesn't match" messages, I have tried to filter them out but with no success. My normal " | grep -v {unwanted string] " syntax is not working, I assume because of how env_logger is outputting the messages that are equal to or above the level requested.

By chance could I trouble you for any tips on how to parse this type of output to eliminate unwanted lines? I was not even able to redirect the output to a file ( " > {filename} ), so I am out of the techniques that I normally employ.

Thanks!

@K4KDR
Copy link
Contributor Author

K4KDR commented Mar 29, 2022

The documentation for env_logger indicates that it outputs to stderr by default, NOT stdout. There may very well be a more simple way, but I accomplished my goal by redirecting the stderr out to a file with:

nc 86.82.68.237 10000 | RUST_LOG=info cargo run --release OSNMA_PublicKey_20210920133026.pem 2> output.txt

... and then in a separate window, monitoring that file with:

tail -f output.txt | grep -v "match word stored"

... which provides cleaner output without all those warnings about "doesn't match word stored for the same subframe"

@daniestevez
Copy link
Owner

Indeed the key is that the log output is going to stderr. You can also do it in one go with

nc 86.82.68.237 10000 | RUST_LOG=info cargo run --release OSNMA_PublicKey_20210920133026.pem 2>&1 | grep -v "match word stored"

@K4KDR
Copy link
Contributor Author

K4KDR commented Mar 30, 2022

I am not surprised that you have a cleaner way to parse the output - thank you!

Hopefully these entry-level questions will be helpful to someone later who searches the ISSUE or DISCUSSION sections.

I have a Galileo-capable GPS receiver coming, so once that arrives I'll try the next steps in your README.

Thanks!

@daniestevez
Copy link
Owner

I'm trying to clean up the issues by closing what is already solved and moving to a discussion what has background information that could be interesting to others. I think this one can be moved to a discussion.

Repository owner locked and limited conversation to collaborators Apr 9, 2022
@daniestevez daniestevez converted this issue into discussion #12 Apr 9, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants