]>
code.octet-stream.net Git - m17rt/blob - m17core/src/address.rs
1 #[derive(Debug, Clone, PartialEq, Eq)]
9 /// ASCII representation of a callsign address.
11 /// May be up to 9 characters long - if it shorter then remaining space is filled with
13 #[derive(Debug, Clone, PartialEq, Eq)]
14 pub struct Callsign(pub [u8; 9]);
16 static ALPHABET
: [u8; 40] = [
17 b' '
, b'A'
, b'B'
, b'C'
, b'D'
, b'E'
, b'F'
, b'G'
, b'H'
, b'I'
, b'J'
, b'K'
, b'L'
, b'M'
, b'N'
, b'O'
,
18 b'P'
, b'Q'
, b'R'
, b'S'
, b'T'
, b'U'
, b'V'
, b'W'
, b'X'
, b'Y'
, b'Z'
, b'
0'
, b'
1'
, b'
2'
, b'
3'
, b'
4'
,
19 b'
5'
, b'
6'
, b'
7'
, b'
8'
, b'
9'
, b'
-'
, b'
/'
, b'
.'
,
23 pub fn decode_address(encoded
: [u8; 6]) -> Address
{
24 let full
= u64::from_be_bytes([
25 0, 0, encoded
[0], encoded
[1], encoded
[2], encoded
[3], encoded
[4], encoded
[5],
28 m @
1..=0xEE6B27FFFFFF => Address
::Callsign(decode_base_40(m
)),
29 m @
0xEE6B28000000..=0xFFFFFFFFFFFE => Address
::Reserved(m
),
30 0xFFFFFFFFFFFF => Address
::Broadcast
,
31 _
=> Address
::Invalid
,
35 fn decode_base_40(mut encoded
: u64) -> Callsign
{
36 let mut callsign
= Callsign([b' '
; 9]);
39 callsign
.0[pos
] = ALPHABET
[(encoded
% 40) as usize];
46 pub fn encode_address(address
: &Address
) -> [u8; 6] {
49 Address
::Invalid
=> (),
50 Address
::Callsign(call
) => {
51 for c
in call
.0.iter
().rev() {
52 let c
= c
.to_ascii_uppercase();
53 if let Some(pos
) = ALPHABET
.iter
().position(|alpha
| *alpha
== c
) {
54 out
= out
* 40 + pos
as u64;
58 Address
::Reserved(m
) => out
= *m
,
59 Address
::Broadcast
=> out
= 0xFFFFFFFFFFFF,
61 out
.to_be_bytes()[2..].try_into().unwrap
()
70 let encoded
= encode_address(&Address
::Callsign(Callsign(
71 b
"AB1CD ".as_slice().try_into().unwrap
(),
73 assert_eq
!(encoded
, [0x00, 0x00, 0x00, 0x9f, 0xdd, 0x51]);
78 let decoded
= decode_address([0x00, 0x00, 0x00, 0x9f, 0xdd, 0x51]);
81 Address
::Callsign(Callsign(b
"AB1CD ".as_slice().try_into().unwrap
()))