
    g.              
          d dl mZ d dlZd dlmZ dedefdZdedefdZ	dedefd	Z
dedefd
ZdedefdZd)dededefdZd)dededefdZdedefdZdedee         fdZdedefdZdedee         fdZdedefdZdedefdZdedefdZdedee         fdZdedee         fdZdedee         fdZdedefdZdedefdZdedefd Zd!ed"ed#ed$edef
d%Zd& Zd' Z d( Z!dS )*    )OptionalN)wraphexstrreturnc                     t          |           dz  }t          t          | d                    dd                             t          |                    }|S )zBConvert a hexadecimal string to binary string, with zero fillings.         N)lenbinintzfill)r   num_of_bitsbinstrs      C/home/andy/.local/lib/python3.11/site-packages/pyModeS/py_common.pyhex2binr      sJ    f++/KVR!!!""%++C,<,<==FM    c                 "    t          | d          S )z(Convert a hexadecimal string to integer.r	   r   )r   s    r   hex2intr      s    vr??r   r   c                 "    t          | d          S )z#Convert a binary string to integer.r
   r   r   s    r   bin2intr      s    vq>>r   c                 H    d                     t          | d                    S )z.Convert a binary string to hexadecimal string.z{0:X}r
   )formatr   r   s    r   bin2hexr      s    >>#fa..)))r   msgc                 z    t          | dd                   }t          t          |dd                   d          S )z*Decode Downlink Format value, bits 1 to 5.Nr
   r         )r   minr   )r   dfbins     r   dfr#      s7    CGEwuQqSz""B'''r   Fencodec                 >   t          dd          t          dd          t          dd          t          dd          g}|r| dd         dz   } t          |           }t          |d	          }t          t	          t
          |                    }t          t          |          d
z
            D ]}t          d	          D ]}d|z	  }||         |z  }	|	dk    r||         |d         |z	  z  ||<   ||dz            d|d         d	|z
  z  |d         |z	  z  z  z  ||dz   <   ||dz            d|d         d	|z
  z  |d         |z	  z  z  z  ||dz   <   ||d
z            d|d         d	|z
  z  |d
         |z	  z  z  z  ||d
z   <   |d         dz  |d         d	z  z  |d         z  }
|
S )a\  Mode-S Cyclic Redundancy Check.

    Detect if bit error occurs in the Mode-S message. When encode option is on,
    the checksum is generated.

    Args:
        msg: 28 bytes hexadecimal message string
        encode: True to encode the date only and return the checksum
    Returns:
        int: message checksum, or partity bits (encoder)

    11111111r
   111110100000010010000000N000000         r         r	   )r   r   r   listmapr   ranger   )r   r$   Gmsgbinmsgbin_splitmbytesibyteibitmaskbitsresults              r   crcr@   #   s    
Z		SQ//Z1C1CSUVEWEWXA "#2#h!S\\F??L#g|,,--Fs6{{Q''  !HH 	 	D4<D%=4'Daxx &u1 >u$*519$5QqTQX-!A$$,?@%uqy! %+519$5QqTQX-!A$$,?@%uqy! %+519$5QqTQX-!A$$,?@%uqy!	  RjB6":?3fRj@FMr   c                    t          j        g d          }t          |          }t          j        d t          |           D                       }|rdgdz  |dd<   t	          t          |          dz
            D ]7}||         dk    rt          j        ||||z            |          ||||z   <   8t          j        |dd         d          d	d
         }t          |          }|S )z7Mode-S Cyclic Redundancy Check. (Legacy code, 2x slow).)r/   r/   r/   r/   r/   r/   r/   r/   r/   r/   r/   r/   r/   r   r/   r   r   r   r   r   r   r/   r   r   r/   c                 ,    g | ]}t          |          S  r   ).0is     r   
<listcomp>zcrc_legacy.<locals>.<listcomp>X   s    666AQ666r   r   r    iN )	separatorr/   r3   )nparrayr   r   r6   bitwise_xorarray2stringr   )r   r$   	generatorngmsgnpbinrE   r8   reminders           r   
crc_legacyrQ   P   s	    SSS I 
YBx6666677H "r 3x==2%&& O OA;!  "~hq1r6z.BINNQV _Xcdd^r:::1R4@FvHOr   xc                 D    t          t          j        |                     S )zMode-S floor function.

    Defined as the greatest integer value k, such that k <= x
    For example: floor(3.6) = 3 and floor(-3.6) = -4

    )r   rI   floor)rR   s    r   rT   rT   l   s     rx{{r   c                     t          |           }|dv r| dd         }n8|dv r2t          | d          }t          | dd         d	          }d
||z  z  }nd}|S )zCalculate the ICAO address from an Mode-S message.

    Applicable only with DF4, DF5, DF20, DF21 messages.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        String: ICAO address in 6 bytes hexadecimal string

    )         r
   r,   )r   r   r   r	         T)r$   r*   Nr	   z%06X)r#   r@   r   )r   DFaddrc0c1s        r   icaor_   v   sx     
CB	\1Q3x	$	$	$T"""RSS2b!Kr   r_   c                    | (t          | t                    rt          |           dk    rdS t          | d          }d|cxk     rdk     rn ndS d|cxk     rdk     rn ndS d	|cxk     rd
k     rn ndS d|cxk     rdk     rn ndS d|cxk     rdk     rn ndS d|cxk     rdk     rn ndS d|cxk     rdk     rn ndS d|cxk     rdk     rn ndS d|cxk     rdk     rn ndS dS )z=Check whether the ICAO address is assigned (Annex 10, Vol 3).N   Fr	   i    i' i  ( i( i  P i_ i  ` ig i  h i  o i   i i   i i   i i   i T)
isinstancestrr   r   )r_   icaoints     r   is_icao_assignedre      s   js33Tau$mmG'$$$$H$$$$$u'$$$$H$$$$$u'$$$$H$$$$$u'$$$$H$$$$$u'$$$$H$$$$$u'$$$$H$$$$$u'$$$$H$$$$$u'$$$$H$$$$$u'$$$$H$$$$$u4r   c                     t          |           dvrdS t          | dd                   }t          |dd                   S )zType code of ADS-B message

    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        int: type code number
    )rW   rX   Nr,   
   r   r   )r#   r   r   )r   tcbins     r   typecoderi      sE     
#wwhtC"IE51:r   latc                    t          j        | d          rdS t          j        t          |           d          rdS | dk    s| dk     rdS d}dt          j        t           j        d|z  z            z
  }t          j        t           j        dz  t          |           z            dz  }dt           j        z  t          j        d||z  z
            z  }t          |          }|S )	zNL() function in CPR decoding.r   ;   W   r
   ir/         )rI   iscloseabscospiarccosrT   )rj   nzabnlNLs         r   cprNLrz      s     
z#q r	CHHb	!	! q	rS3YYq	B	BF25AF#$$$A
rus{SXX%&&!+A	
RUbiAE	**	+B	rBIr   c                     t          |           dvrt          d          t          |           }|dd         }t          |          S )zCompute identity code (squawk) encoded in DF5 or DF21 message.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        string: squawk code

    )r   rZ   z(Message must be Downlink Format 5 or 21.       )r#   RuntimeErrorr   squawk)r   mbin	idcodebins      r   idcoder      sJ     
#wwgEFFF3<<DRUI)r   c                    t          |           dk    s/t          |                               t          d                    st          d          | d         }| d         }| d         }| d         }| d         }| d	         }| d
         }| d         }| d         }	| d         }
| d         }| d         }t	          ||z   |z   d          }t	          ||	z   |z   d          }t	          ||z   |z   d          }t	          ||
z   |z   d          }t          |          t          |          z   t          |          z   t          |          z   S )zDecode 13 bits identity (squawk) code.

    Args:
        binstr (String): 13 bits binary string

    Returns:
        string: squawk code

       01#Input must be 13 bits binary stringr   r/   r
   r-   r   r      r,   	   rg   rV      )r   setissubsetr~   r   rc   )r   C1A1C2A2C4A4B1D1B2D2B4D4byte1byte2byte3byte4s                    r   r   r      s8    6{{bF 4 4SYY ? ?@AAA	B	B	B	B	B	B	B	B	B	B	B	BR"a  ER"a  ER"a  ER"a  Eu::E

"SZZ/#e**<<r   c                     t          |           dvrt          d          t          |           }|dd         }t          |          }|S )zCompute altitude encoded in DF4 or DF20 message.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        int: altitude in ft

    )r   r   r	   rY   z0Message must be Downlink Format 0, 4, 16, or 20.r|   r}   )r#   r~   r   altitude)r   r   altitude_codealts       r   altcoder     sP     
#wwn$$MNNN 3<<DBKM
=
!
!CJr   c                     t          |           dk    s/t          |                               t          d                    st          d          | d         }| d         }t	          |           dk    rd}n|dk    r|d	k    r3| dd         | d
         z   | dd         z   }t	          |          dz  dz
  }|dk    r| d         }| d         }| d         }| d         }| d         }	| d         }
| d
         }| d         }| d         }| d         }| d         }||z   |z   |z   |
z   |z   |z   |z   |z   |z   |	z   }t          |          }|d	k    r4| dd         | d
d         z   }t          t	          |          dz            }|S )zDecode 13 bits altitude code.

    Args:
        binstr (String): 13 bits binary string

    Returns:
        int: altitude in ft

    r   r   r   ra   r,   r   N01r   r      i  r/   r
   r-   r   r   rg   rV   r   gD
)?
@)r   r   r   r~   r   gray2altr   )r   MbitQbitr   vbinr   r   r   r   r   r   r   r   r   r   r   graystrs                    r   r   r     s    6{{bF 4 4SYY ? ?@AAA!9D!9Dv!	3;;"1":q	)F122J6D$--"$t+C3;;BBBBBBBBBBB2glR'",r1B6;b@2EJG7##Cs{{bqbzF122J&'$--')**Jr   c                     | d d         }t          |          }| dd          }t          |          }|dv rd S |dk    rd}|dz  rd|z
  }|dz  |dz  z   d	z
  }|S )
Nr,   )r   r   ra   r   r   r
   ra   i  d   i  )gray2int)r   gc500n500gc100n100r   s         r   r   r   R  s    2A2JEE??D 122JEE??Dytqyyax 4x#:s
"d
*CJr   c                 d    t          |           }||dz	  z  }||dz	  z  }||dz	  z  }||dz	  z  }|S )zConvert greycode to binary.r,   r   r
   r/   )r   )r   nums     r   r   r   g  sF    
&//C3!8OC3!8OC3!8OC3!8OCJr   c                     | dd         S )z4Return the data frame in the message, bytes 9 to 22.r,   r*   rC   )r   s    r   datar   q  s    qt9r   c                 h    t          t          |                     }t          |          dk    rdS dS )zCheck if the data bits are all zeros.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False

    r   FT)r   r   r   )r   ds     r   allzerosr   v  s0     	S		AqzzA~~utr   r   sbmsblsbc                 ~    t          | |dz
                     }t          | |dz
  |                   }|s|dk    rdS dS )zxCheck if the status bit and field bits are consistency.

    This Function is used for checking BDS code versions.

    r/   r   TF)r   r   )r   r   r   r   statusvalues         r   wrongstatusr     sN     b1fFDq3'((E A::45r   c                     t          |           }t          |dd                   }d}|dk    rd}n,|dk    rd}n#|dk    rd	}n|d
k    rd}n|dk    rd}n|dk    rd}||fS )zDecode flight status for DF 4, 5, 20, and 21.

    Args:
        msg (str): 14 hexdigits string
    Returns:
        int, str: flight status, description

    r   r,   Nr   z&no alert, no SPI, aircraft is airborner/   z'no alert, no SPI, aircraft is on-groundr
   z#alert, no SPI, aircraft is airborner-   z$alert, no SPI, aircraft is on-groundr   z-alert, SPI, aircraft is airborne or on-groundz0no alert, SPI, aircraft is airborne or on-groundr   r   )r   r8   fstexts       r   r   r     s     S\\F	!		BD	Qww7	q8	q4	q5	q>	qAt8Or   c                     t          |           }t          |dd                   }d}|dk    rd}n9|dk    rd}n0|dk    rd	}n'|d
k    rd}n|dk    rd                    |dz
            }||fS )zDecode downlink request for DF 4, 5, 20, and 21.

    Args:
        msg (str): 14 hexdigits string
    Returns:
        int, str: downlink request, description

    r,   r   Nr   zno downlink requestr/   zrequest to send Comm-B messager   zComm-B broadcast 1 availabler   zComm-B broadcast 2 availabler	   z#ELM downlink segments available: {}rn   )r   r   r   )r   r8   drr   s       r   r   r     s     S\\F	"		BD	Qww$	q/	q-	q-	r4;;BGDDt8Or   c                     t          |           }t          |dd                   }t          |dd                   }|dk    rd}|dk    rd}|dk    rd	}|d
k    rd}|||fS )a>  Decode utility message for DF 4, 5, 20, and 21.

    Utility message contains interrogator identifier and reservation type.

    Args:
        msg (str): 14 hexdigits string
    Returns:
        int, str: interrogator identifier code that triggered the reply, and
        reservation type made by the interrogator
    r   rW   r|   r   Nr/   z#Comm-B interrogator identifier coder
   z#Comm-C interrogator identifier coder-   z#Comm-D interrogator identifier coder   )r   r8   iisidsids_texts        r   umr     s~     S\\F
&B-
 
 C
&B-
 
 C
axx
axx8
axx8
axx8Xr   )F)"typingr   numpyrI   textwrapr   rc   r   r   r   r   r   r#   boolr@   rQ   floatrT   r_   re   ri   rz   r   r   r   r   r   r   r   r   r   r   r   r   rC   r   r   <module>r      sz                  C C    C C    
C C    
*C *C * * * *
(C (C ( ( ( (* *S *$ *3 * * * *Z C  #    8U s    c hsm    63 4    :# (3-     u     $     & =3  =3  =  =  =  =F #    20S 0Xc] 0 0 0 0fS Xc]    *S S    c c    
# $    $c s  3 4    "  :  8    r   