#
#  gpsman --- GPS Manager: a manager for GPS receiver data
#
#  Copyright (c) 2007 Miguel Filgueiras (mig@ncc.up.pt) / Universidade do Porto
#
#    This program is free software; you can redistribute it and/or modify
#      it under the terms of the GNU General Public License as published by
#      the Free Software Foundation; either version 2 of the License, or
#      (at your option) any later version.
#
#      This program is distributed in the hope that it will be useful,
#      but WITHOUT ANY WARRANTY; without even the implied warranty of
#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#      GNU General Public License for more details.
#
#      You should have received a copy of the GNU General Public License
#      along with this program.
#
#  File: garmin_protocols.tcl
#  Last change:  31 May 2007
#

# description of Garmin protocols based on Garmin GPS Interface
#  Specification Version 1 Rev. 2
# updated for:
#   Garmin GPS Interface Specification Version 1 Rev. 3
#   Garmin GPS Interface Specification Version 1 Rev. A
#   Garmin GPS Interface Specification Version 1 Rev. B
#   Garmin GPS Interface Specification Version 1 Rev. C

# Garmin USB protocol is implemented assuming that the USB port is driven by
#  the garmin_gps Linux kernel driver by Hermann Kneissel and part of the
#  official 2.6 Linux kernel releases

   # ASCII codes (decimal)
set DLE 16
set ETX 3
set ACK 6
set NAK 21

   # DLE char 
set DLECHR [binary format "c" $DLE]

   # protocol tags
array set PROTTAG {
    P Physical  L Link  A Application  D Data  T nospec
}

   # categories of known product specific protocols
set PSPROTOCOLS {Link DevCmd WP WPCat RT TR LAP Prx AL DtTm
                 FlightBook Posn PVT}

   # application protocol categories
array set PROTCAT {
    A010  DevCmd
    A011  DevCmd
    A100  WP
    A101  WPCat
    A200  RT
    A201  RT
    A300  TR
    A301  TR
    A302  TR
    A400  Prx
    A500  AL
    A600  DtTm
    A601  nospec
    A650  FlightBook
    A700  Posn
    A800  PVT
    A801  nospec
    A802  nospec
    A900  nospec
    A901  nospec
    A902  nospec
    A903  nospec
    A904  nospec
    A905  nospec
    A906  LAP
    A907  nospec
    A908  nospec
    A913  nospec
    A914  nospec
    A916  nospec
    A917  nospec
    A918  nospec
    A1000 RUN
    A1002 WKO
    A1003 WKOOcc
    A1004 FUP
    A1005 WKOLimits
    A1006 nospec
    A1007 nospec
    A1008 nospec
    A1009 CRSLimits
    A1010 nospec
    A1011 nospec
}

   # protocol requirements
array set PROTREQ {
    N/A   ""
    P000  ""
    L000  ""
    L001  ""
    L002  ""
    A010  ""
    A011  ""
    A100  WPData
    A101  WPCatData
    A200  {RTHeader RTWPData}
    A201  {RTHeader RTWPData RTLinkData}
    A300  TRData
    A301  {TRHeader TRData}
    A302  {TRHeader TRData}
    A400  PrxWPData
    A500  ALData
    A600  DtTmData
    A601  D?
    A650  ""
    A700  PosnData
    A800  PVTData
    A801  D?
    A802  D?
    A900  ""
    A901  D?
    A902  ""
    A903  ""
    A904  ""
    A905  D?
    A906  LAPData
    A907  {D? D? D? D?}
    A908  D?
    A913  ""
    A914  ""
    A916  ""
    A917  D?
    A918  D?
    A1000 RUNData
    A1002 WKOData
    A1003 WKOOcc
    A1004 FUPData
    A1005 WKOLimits
    A1006 CRSData
    A1007 D?
    A1008 D?
    A1009 CRSLimits
    A1010 ""
    A1011 ""
}

   # Garmin USB Protocol
array set GUSB {
    LAYERID,TRANSPORT  0
    LAYERID,APPL 20
    LAYERID,PRIVATE  0x01106E4B
    PRIV,PID,SET,DEBUG    1
    PRIV,PID,SET,MODE     2
    PRIV,PID,INFO,REQ     3
    PRIV,PID,INFO,RESP    4
    PRIV,PID,RESET,REQ    5
    PRIV,PID,SET,DEF,MODE 6
    MODE,NATIVE          0
    MODE,GARMIN,SERIAL   1
    PID,TRANSPORT,DATA,AVAILABLE 2
    PID,TRANSPORT,START,SESSION,REQ 5
    PID,TRANSPORT,START,SESSION,RESP 6
}

   # Basic Link Protocol
array set PID {
    ACK           6
    NAK          21
    PrdExtData  248
    PArray      253
    PrdReq      254
    PrdData     255
}

array set RPID {
    6           ACK
    21          NAK
    248  PrdExtData
    253      PArray
    254      PrdReq
    255     PrdData
}

   # definitions of Link product specific protocols
set PSPDEF(L001) {{CmdData 10} {XfrCmpl 12} {DtTmData 14} {PosnData 17}
                  {PrxWPData 19} {Records 27} {RTHeader 29} {RTWPData 30}
                  {ALData 31} {TRData 34} {WPData 35} {PVTData 51}
                  {RTLinkData 98} {TRHeader 99} {FlightBook_Record 134}
                  {LAPData 149} {WPCatData 152} {RUNData 990} {WKOData 991}
                  {WKOOcc 992} {FUPData 993} {WKOLimits 994} {CRSData 1061}
                  {CRSLap 1062} {CRSPoint 1063} {CRSTRHeader 1064}
                  {CRSTRData 1065} {CRSLimits 1066}}

set PSPDEF(L002) {{ALData 4} {CmdData 11} {XfrCmpl 12} {DtTmData 20}
                  {PosnData 24} {PrxWPData 27} {Records 35} {RTHeader 37}
                  {RTWPData 39} {WPData 43}}

    # packet ids not described in the specifications:
    #   114: appears before a PVTData packet in the Quest

    # definition of product specific device commands
set PSCMDDEF(A010) {{Abort 0} {XfrAL 1} {XfrPosnData 2} {XfrPrx 3} {XfrRT 4}
                  {XfrDtTmData 5} {XfrTR 6} {XfrWP 7} {TurnOff 8} {StartPVT 49}
                  {StopPVT 50} {XfrFlightBook 92} {XfrLAP 117} {XfrWPCat 121}
                  {XfrRUN 450} {XfrWKO 451} {XfrWKOOcc 452} {XfrFUP 453}
                  {XfrWKOLimits 454} {XfrCRS 561} {XfrCRSLap 562}
                  {XfrCRSPoint 563} {XfrCRSTrack 564} {XfrCRSLimits 565}}
set PSCMDDEF(A011) {{Abort 0} {XfrAL 1} {XfrRT 8} {XfrPrx 17} {XfrDtTmData 20}
                  {XfrWP 21} {TurnOff 26}}

    # size in bytes of data types used in unions
    # unions are only used if there is a single data item and sizes of
    #  types in the union must be all different
array set PDTSIZE {
    byte 1
    int  2
}

    # protocol data types

      # data type for ACK/NAK packet; this is now set in proc FixACKNAKType
      #  when the first such packet is received
      # sending 16-bit int according to Garmin specifications versions < 3
      #  but accepting either int or byte as in versions <= 3
set PDTYPE(ACK) union=int,byte
set PDTYPE(NAK) union=int,byte

      # sending byte according to Garmin specifications version 3
      #  and accepting either int or byte as in versions <= 3
# set PDTYPE(ACK) union=byte,int
# set PDTYPE(NAK) union=byte,int

    # protocols for which no output is available (as in the Garmin specs,
    #  or because of no support or no complete specification available)
    # list of pairs with item type and either empty (for any) or list of
    #  pairs with protocol type and protocol identifier

set PROTNOOUTPUT {{TR {{TR A302} {TRData D304}}} {Prx {}} {AL {}}}

array set PDTYPE {
    PArray  starray=char,word
    PrdReq  ignored
    PrdData    {int int string ignored}
    PrdExtData ignored
    Records  int
    D100  {charray=6 semicircle unused=4 charray=40}
    D101  {charray=6 semicircle unused=4 charray=40 float byte}
    D102  {charray=6 semicircle unused=4 charray=40 float int}
    D103  {charray=6 semicircle unused=4 charray=40 byte byte}
    D104  {charray=6 semicircle unused=4 charray=40 float int byte}
    D105  {semicircle int string}
    D106  {byte bytes=13 semicircle int string string}
    D107  {charray=6 semicircle unused=4 charray=40 byte byte float byte}
    D108  {byte byte byte byte int bytes=18 semicircle float float float
           charray=2 charray=2 string string string string string string}
    D109  {byte byte byte byte int bytes=18 semicircle float float float
           charray=2 charray=2 longword string string string string string
	   string}
    D110  {byte byte byte byte int bytes=18 semicircle float float float
           charray=2 charray=2 longword float longword int string string string
	   string string string}
    D120  {string<17}
    D150  {charray=6 charray=2 byte semicircle int charray=24 charray=2
	   charray=30 charray=40}
    D151  {charray=6 semicircle unused=4 charray=40 float charray=30
           charray=24 charray=2 int charray=2 unused=1 byte}
    D152  {charray=6 semicircle unused=4 charray=40 float charray=30
           charray=24 charray=2 int charray=2 unused=1 byte}
    D154  {charray=6 semicircle unused=4 charray=40 float charray=30
           charray=24 charray=2 int charray=2 unused=1 byte int}
    D155  {charray=6 semicircle unused=4 charray=40 float charray=30
           charray=24 charray=2 int charray=2 unused=1 byte int byte}
    D200  byte
    D201  {byte charray=20}
    D202  string
    D210  {word bytes=18 string}
    D300  {semicircle longword boolean}
    D301  {semicircle longword float float boolean}
    D302  {semicircle longword float float float boolean}
    D303  {semicircle longword float byte}
    D304  {semicircle longword float float byte byte boolean}
    D310  {boolean byte string}
    D311  word
    D312  {boolean byte string}
    D400  {charray=6 semicircle unused=4 charray=40 float}
    D403  {charray=6 semicircle unused=4 charray=40 byte byte float}
    D450  {int charray=6 charray=2 byte semicircle int charray=24 charray=2
	   charray=30 charray=40 float}
    D500  {int float float float float float float float float float float}
    D501  {int float float float float float float float float float float
           byte}
    D550  {byte int float float float float float float float float float
	   float}
    D551  {byte int float float float float float float float float float
	   float byte}
    D600  {byte byte word int byte byte}
    D601  nospec
    D650  {longword longword semicircle semicircle longword longword float
           float float boolean string string string string string}
    D700  radian
    D800  {float float float float int double radian float float float float
           int long}
    D801  nospec
    D802  nospec
    D900  nospec
    D901  nospec
    D906  {longword longword float semicircle semicircle word byte byte}
    D907  nospec
    D908  nospec
    D909  nospec
    D910  nospec
    D911  nospec
    D917  nospec
    D918  nospec
    D1003 nospec
    D1004 nospec
    D1005 nospec
    D1006 nospec
    D1007 nospec
    D1008 nospec
    D1009 nospec
    D1011 nospec
    D1012 nospec
    D1013 nospec
}

## RT/TR Header protocols with a numeric identifier
set PRTNUMID {D200 D201}
set PTRNUMID {D311}

    # product identifiers; new entries should also be added to recmodels.tcl
    #  numbers followed by a letter are defined here to support older
    #  software versions; not following Garmin specs in this
array set PRODID {
    "GPS 50" 7  
    "GPS 75" {13 23 42}
    "GPS 55" 14
    "GPS 55 AVD" 15
    "GPS 65" 18
    "GPS 95 AVD" {22 36}
    "GPS 95" {24 35}
    "GPS 85" 25
    "GPSMAP 205" {29 44}
    "GPSMAP 210" 29
    "GPSMAP 220" 29
    "GPS 40" {31 41}
    "GPS 45" {31 41}
    "GPS 95 XL" 36
    "GPS 89" 39
    "GPS 38" 41
    "GPS 45 XL" 41
    "GPS 90" 45
    "GPS 120" 47
    "GPSMAP 195" 48
    "GPSMAP 130" 49
    "GPSMAP 135 Sounder" 49
    "GPSMAP 175" 49
    "GPSMAP 230" 49
    "GPSMAP 235 Sounder" 49
    "GPSCOM 170" 50
    "GPSCOM 190" 53
    "GPS 120 Chinese" 55
    "GPS 38 Chinese" 56
    "GPS 40 Chinese" 56
    "GPS 45 Chinese" 56
    "GPS II" 59
    "GPS 125 Sounder" 61
    "GPS 38 Japanese" 62
    "GPS 40 Japanese" 62
    "GPS III Pilot" 71
    "GPS III" 72
    "GPS II Plus" {73 97}
    "GPS 120 XL" 74
    "GPSMAP 130 Chinese" 76
    "GPSMAP 230 Chinese" 76
    "GPS 12" {77 87 96}
    "GPS 12 XL" {77 96}
    "GPS 12 XL - software < 3.01" 77a
    "GPSMAP 215" 88
    "GPSMAP 225" 88
    "GPSMAP 180" 89
    "GPS 126" 95
    "GPS 128" 95
    "GPS 48" 96
    "GPS 126 Chinese" 100
    "GPS 128 Chinese" 100
    "GPS 12 Arabic" 103
    "GPS 12 XL Japanese" 105
    "GPS 12 XL Chinese" 106
    eMap   111
    "GPS 92" 112
    "GPS 12CX" 116
    "GPS III Plus" 119
    "GPSMAP 295" 128
    "GPS 12 Map" 129
    eTrex  130
    "GPSMAP 176" 136
    "GPS 12 4.58" 138
    "eTrex Summit"  {141 295}
    "GPSMAP 196" 145
    "StreetPilot 3" 151
    "eTrex Venture/Mariner"  154
    "GPS 5"  155
    "eTrex Euro"  156
    "eTrex Vista" {169 420}
    "GPS 76" 173
    "GPSMAP 76" 177
    "eTrex Legend" {179 411}
    "GPSMAP 76S" 194
    "Rino 110"   197
    "Rino 120"   209
    "Quest" 231
    "GPS 72" 247
    "Geko 201" 248
    "Geko 301" 256
    "Rino 130" 264
    "GPS 18USB" 273
    "Forerunner" 282
    "Forerunner 301" 283
    "GPSmap 276C" 285
    "GPS 60" 289
    "GPSMap60C" 291
    "GPSMap60CSX" 292
    "GPSMap76CSX" 292
    "GPSMap60" 308
    "ForeTrex" 314
    "eTrex Vista C" 315
    "eTrex Legend C" 315
    "eTrex Venture" 419
    "eTrex Legend Cx" 421
    "EDGE205" 450
    "EDGE305" 450
    "Forerunner 205" 484
    "Forerunner 305" 484
    "StreetPilot i2" 532
}

    # product names and how to obain its product specific protocols
    #  valid values for $PRTCLDEF($product_id) are
    #   array   set PSPID($product_id,$name_prod_spec_prot) to protocol
    #            to use, for each $name_prod_spec_prot
    #   see=$ID use the same protocols as product $ID
    #   diff    set PSDIFF($product_id) to list whose head is a product id
    #            and whose tail contains pairs of $name_prod_spec_prot and
    #            protocol to use; these pairs describe the differences to
    #            the other product and must not contain Link or DevCmd

array set PNAME {
     7  "GPS 50"
    13  "GPS 75"
    14  "GPS 55"
    15  "GPS 55 AVD"
    18  "GPS 65"
    22  "GPS 95 AVD"
    23  "GPS 75"
    24  "GPS 95"
    25  "GPS 85"
    29a  "GPSMAP 205/210/220 - <4.0"
    29  "GPSMAP 205/210/220"
    31  "GPS 40/45"
    35  "GPS 95"
    36a  "GPS 95 AVD/XL - < 3.0"
    36  "GPS 95 AVD/XL"
    39  "GPS 89"
    41  "GPS 38/40/45/45 XL"
    42  "GPS 75"
    44  "GPSMAP 205"
    45  "GPS 90"
    47  "GPS 120"
    48  "GPSMAP 195"
    49  "GPSMAP 130/135 Sounder/175/230/235 Sounder"
    50  "GPSCOM 170"
    53  "GPSCOM 190"
    55  "GPS 120 Chinese"
    56  "GPS 38/40/45 Chinese"
    59  "GPS II"
    61  "GPS 125 Sounder"
    62  "GPS 38 Japanese/40 Japanese"
    71  "GPS III Pilot"
    72  "GPS III"
    73  "GPS II Plus"
    74  "GPS 120 XL"
    76  "GPSMAP 130 Chinese/230 Chinese"
    77a "GPS 12 XL - < 3.01"
    77b "GPS 12 XL - 3.01 < 3.50"
    77c "GPS 12 XL - 3.50 < 3.61"
    77  "GPS 12/12 XL"
    87  "GPS 12"
    88  "GPSMAP 215/225"
    89  "GPSMAP 180"
    95  "GPS 126/128"
    96  "GPS 12/12 XL/48"
    97  "GPS II Plus"
    100  "GPS 126 Chinese/128 Chinese"
    103  "GPS 12 Arabic"
    105  "GPS 12 XL Japanese"
    106  "GPS 12 XL Chinese"
    119  "GPS III Plus"
    111  eMap
    112  "GPS 92"
    116  "GPS 12CX"
    128  "GPSMAP 295"
    129  "GPS 12 Map"
    130  eTrex
    136  "GPSMAP 176"
    138  "GPS 12"
    141  "eTrex Summit"
    145  "GPSMAP 196"
    151  "StreetPilot 3"
    154  "eTrex Venture/Mariner"
    155  "GPS 5"
    156  "eTrex Euro"
    169  "eTrex Vista"
    173  "GPS 76"
    177  "GPSMAP 76"
    179  "eTrex Legend"
    194  "GPSMAP 76S"
    197  "Rino 110"
    209  "Rino 120"
    231  "Quest"
    247  "GPS 72"
    248  "Geko 201"
    256  "Geko 301"
    264  "Rino 130"
    273  "GPS 18USB"
    282  "Forerunner"
    283  "Forerunner 301"
    285  "GPSmap 276C"
    289  "GPS 60"
    291  "GPSMap60C"
    292  "GPSMap60CSX/76CSX"
    295  "eTrex Summit"
    308  "GPSMap60"
    314  "ForeTrex"
    315  "eTrex Vista/Legend C"
    411  "eTrex Legend"
    419  "eTrex Venture"
    420  "eTrex Vista"
    421  "eTrex Legend Cx"
    450  "EDGE205/305"
    484  "Forerunner 205/305"
    532  "StreetPilot i2"
}

# the descriptions below are valid for all versions except:
#  29 version < 4.0
#  29+ version >= 4.0
#  36 version < 3.0
#  36+ version >= 3.0
#  77, 77+, 77++ versions < 3.01, < 3.50, < 3.61
#  77+++  version >= 3.61
#  111 version < 2.7
#  111+ version >= 2.7
#  285 version < 3.0 (just a guess)
#  285+ version >= 3.0
#  484 version < 2.6 (just a guess)
#  484+ version >= 2.6

      # the pairs in the following entries have a comparison to be made
      #  to the receiver version and the identifier to be used if the
      #  comparison succeeds
array set PRTCLVERSION {
    29  {{{>= 400} 29+}}
    36  {{{>= 300} 36+}}
    77  {{{>= 361} 77+++} {{>= 350} 77++} {{>= 301} 77+}}
    111 {{{>= 270} 111+}}
    285 {{{>= 300} 285+}}
    289 {{{>= 240} 289+}}
    484 {{{>= 260} 484+}}
}

array set PRTCLDEF {
     7  diff
    13  diff
    14  diff
    15  diff
    18  see=13
    22  diff
    23  see=13
    24  see=13
    25  see=13
    29  diff
    29+ diff
    31  see=59
    35  see=13
    36  see=22
    36+ see=45
    39  diff
    41  see=59
    42  see=13
    44  see=29
    45  diff
    47  see=59
    48  diff
    49  diff
    50  diff
    53  see=50
    55  see=59
    56  see=59
    59  array
    61  see=59
    62  see=59
    71  diff
    72  diff
    73  diff
    74  see=59
    76  see=49
    77  diff
    77+ diff
    77++ see=73
    77+++  see=77+
    87  see=77+
    88  see=49
    89  see=29+
    95  see=77+
    96  see=77+
    97  see=73
    100  see=77+
    103  see=77+
    105  see=77+
    106  see=77+
    111  array
    111+ diff
    112  diff
    116  array
    119  array
    128  see=111
    129  array
    130  diff
    136  diff
    138  see=77+
    141  see=130
    145  array
    151  array
    154  see=130
    155  diff
    156  see=130
    169  see=130
    173  see=177
    177  array
    179  see=130
    194  see=177
    197  diff
    209  see=197
    231  array
    247  see=116
    248  array
    256  diff
    264  diff
    273  array
    282  array
    283  array
    285  see=291
    285+ array
    289  see=315
    289+ diff
    291  array
    292  array
    295  see=248
    308  see=289+
    314  array
    315  array
    411  diff
    419  array
    420  see=411
    421  array
    450  array
    484  diff
    484+ diff
    532  array
}

### there is no information on which receivers use the PVT protocol
# and therefore it is assumed all can use it

array set PSPID {
    59,Link  L001
    59,DevCmd  A010
    59,WP  A100
    59,WPData  D100
    59,RT  A200
    59,RTHeader  D201
    59,RTWPData  D100
    59,TR  A300
    59,TRData  D300
    59,Prx  N/A
    59,AL  A500
    59,ALData  D500
    59,DtTm  A600
    59,DtTmData  D600
    59,Posn  A700
    59,PosnData  D700
    59,PVT   A800
    59,PVTData   D800

    111,Link  L001
    111,DevCmd  A010
    111,WP  A100
    111,WPData  D108
    111,RT  A201
    111,RTHeader  D201
    111,RTWPData  D108
    111,RTLinkData  D210
    111,TR  A301
    111,TRHeader  D310
    111,TRData  D301
    111,Prx  A400
    111,PrxWPData D108
    111,AL  A500
    111,ALData  D500
    111,DtTm  A600
    111,DtTmData  D600
    111,Posn  A700
    111,PosnData  D700
    111,PVT  A800
    111,PVTData D800

    116,Link L001
    116,DevCmd  A010
    116,WP  A100
    116,WPData  D107
    116,RT  A200
    116,RTHeader  D201
    116,RTWPData  D107
    116,TR  A300
    116,TRData  D300
    116,Prx  A400
    116,PrxWPData D107
    116,AL  A500
    116,ALData  D501
    116,DtTm  A600
    116,DtTmData  D600
    116,Posn  A700
    116,PosnData  D700
    116,PVT  A800
    116,PVTData D800

    119,Link  L001
    119,DevCmd  A010
    119,WP  A100
    119,WPData  D104
    119,RT  A200
    119,RTHeader  D201
    119,RTWPData  D104
    119,TR  A300
    119,TRData  D300
    119,Prx  N/A
    119,AL  A500
    119,ALData  D501
    119,DtTm  A600
    119,DtTmData  D600
    119,Posn  A700
    119,PosnData  D700
    119,PVT  A800
    119,PVTData D800

    129,Link  L001
    129,DevCmd  A010
    129,WP  A100
    129,WPData  D104
    129,RT  A200
    129,RTHeader  D201
    129,RTWPData  D104
    129,TR  A300
    129,TRData  D300
    129,Prx  N/A
    129,AL  A500
    129,ALData  D501
    129,DtTm  A600
    129,DtTmData  D600
    129,Posn  A700
    129,PosnData  D700
    129,PVT  A800
    129,PVTData D800
    129,nospec A900

    145,Link  L001
    145,DevCmd  A010
    145,WP  A100
    145,WPData  D109
    145,RT  A201
    145,RTHeader  D202
    145,RTWPData  D109
    145,RTLinkData  D210
    145,TR  A301
    145,TRHeader  D310
    145,TRData  D301
    145,Prx  A400
    145,PrxWPData  D109
    145,AL  A500
    145,ALData  D501
    145,DtTm  A600
    145,DtTmData  D600
    145,Posn  A700
    145,PosnData  D700
    145,PVT  A800
    145,PVTData  D800
    145,nospec  A650+D650+A900+A901+D901+A902+A903+A904

    151,Link  L001
    151,DevCmd  A010
    151,WP  A100
    151,WPData  D109
    151,RT  A201
    151,RTHeader  D202
    151,RTWPData  D109
    151,RTLinkData  D210
    151,TR  A301
    151,TRHeader  D310
    151,TRData  D301
    151,Prx  N/A
    151,AL  A500
    151,ALData  D501
    151,DtTm  A600
    151,DtTmData  D600
    151,Posn  A700
    151,PosnData  D700
    151,PVT  A800
    151,PVTData  D800
    151,nospec  A900+A902+A903+A904

    177,Link  L001
    177,DevCmd  A010
    177,WP  A100
    177,WPData  D109
    177,RT  A201
    177,RTHeader  D202
    177,RTWPData  D109
    177,RTLinkData  D210
    177,TR  A301
    177,TRHeader  D310
    177,TRData  D301
    177,Prx  A400
    177,PrxWPData D109
    177,AL  A500
    177,ALData  D501
    177,DtTm  A600
    177,DtTmData  D600
    177,Posn  A700
    177,PosnData  D700
    177,PVT  A800
    177,PVTData D800
    177,nospec A900+A902+A903

    231,Link L001
    231,DevCmd A010
    231,WP A100
    231,WPData D110
    231,WPCat A101
    231,WPCatData D120
    231,RT A201
    231,RTHeader D202
    231,RTWPData D110
    231,RTLinkData D210
    231,TR A301
    231,TRHeader D312
    231,TRData D302
    231,Prx N/A
    231,AL A500
    231,ALData D501
    231,DtTm A600
    231,DtTmData D600
    231,Posn A700
    231,PosnData D700
    231,PVT A800
    231,PVTData D800
    231,nospec T+A601+D601+A900+A902+A903+A904+A905

    248,Link L001
    248,DevCmd A010
    248,WP A100
    248,WPData D108
    248,RT A201
    248,RTHeader D202
    248,RTWPData D108
    248,RTLinkData D210
    248,TR A301
    248,TRHeader D310
    248,TRData D301
    248,Prx  N/A
    248,AL A500
    248,ALData D501
    248,DtTm A600
    248,DtTmData D600
    248,Posn A700
    248,PosnData D700
    248,PVT A800
    248,PVTData D800

    273,Link L001
    273,DevCmd A010
    273,WP N/A
    273,RT N/A
    273,TR N/A
    273,Prx  N/A
    273,AL A500
    273,ALData D501
    273,DtTm A600
    273,DtTmData D600
    273,Posn A700
    273,PosnData D700
    273,PVT A800
    273,PVTData D800
    273,nospec A601+D601+A801+D801+A802+D802+A902+A903

    282,Link L001
    282,DevCmd A010
    282,WP A100
    282,WPData D108
    282,RT N/A
    282,TR A302
    282,TRHeader D311
    282,TRData D301
    282,Prx  N/A
    282,AL A500
    282,ALData D501
    282,DtTm A600
    282,DtTmData D600
    282,Posn A700
    282,PosnData D700
    282,PVT A800
    282,PVTData D800
    282,LAP A906
    282,LAPData D906
    282,nospec A802+A903

    283,Link L001
    283,DevCmd A010
    283,WP A100
    283,WPData D110
    283,RT A201
    283,RTHeader D202
    283,RTWPData D110
    283,RTLinkData D210
    283,TR A302
    283,TRHeader D311
    283,TRData D301
    283,Prx  N/A
    283,AL A500
    283,ALData D501
    283,DtTm A600
    283,DtTmData D600
    283,Posn A700
    283,PosnData D700
    283,PVT A800
    283,PVTData D800
    283,LAP A906
    283,LAPData D906

    285+,Link L001
    285+,DevCmd A010
    285+,WP A100
    285+,WPData D110
    285+,WPCat A101
    285+,WPCatData D120
    285+,RT A201
    285+,RTHeader D202
    285+,RTWPData D110
    285+,RTLinkData D210
    285+,TR A301
    285+,TRHeader D312
    285+,TRData D302
    285+,Prx A400
    285+,PrxWPData D110
    285+,AL A500
    285+,ALData D501
    285+,DtTm A600
    285+,DtTmData D600
    285+,Posn A700
    285+,PosnData D700
    285+,PVT A800
    285+,PVTData D800
    285+,LAP A906
    285+,LAPData D906
    285+,nospec T+A601+D601+A802+D802A900+A902+A903+A904+A907+D907+D908+D909+D910

    291,Link L001
    291,DevCmd A010
    291,WP A100
    291,WPData D109
    291,RT A201
    291,RTHeader D202
    291,RTWPData D109
    291,RTLinkData D210
    291,TR A301
    291,TRHeader D310
    291,TRData D301
    291,Prx A400
    291,PrxWPData D109
    291,AL A500
    291,ALData D501
    291,DtTm A600
    291,DtTmData D600
    291,Posn A700
    291,PosnData D700
    291,PVT A800
    291,PVTData D800
    291,nospec A601+D601+A900+A902+A903+A904

    292,Link L001
    292,DevCmd A010
    292,WP A100
    292,WPData D110
    292,RT A201
    292,RTHeader D202
    292,RTWPData D110
    292,RTLinkData D210
    292,TR A301
    292,TRHeader D312
    292,TRData D302
    292,Prx A400
    292,PrxWPData D110
    292,AL A500
    292,ALData D501
    292,DtTm A600
    292,DtTmData D600
    292,Posn A700
    292,PosnData D700
    292,PVT A800
    292,PVTData D800
    292,nospec A601+D601+A801+D801+A900+A902+A903+A904+A907+D907+D908+D909+D910+A908+D911+A914+A916+A917+D917+A918+D918+A1010+A1011

    314,Link L001
    314,DevCmd A010
    314,WP A100
    314,WPData D108
    314,RT A201
    314,RTHeade D202
    314,RTWPData D108
    314,RTLinkData D210
    314,TR A301
    314,TRHeader D310
    314,TRData D301
    314,Prx N/A
    314,AL A500
    314,ALData D501
    314,DtTm A600
    314,DtTmData D600
    314,Posn A700
    314,PosnData D700
    314,PVT A800
    314,PVTData D800
    314,nospec A802+D802+A903

    315,Link L001
    315,DevCmd A010
    315,WP A100
    315,WPData D109
    315,RT A201
    315,RTHeader D202
    315,RTWPData D109
    315,RTLinkData D210
    315,TR A301
    315,TRHeader D310
    315,TRData D301
    315,Prx A400
    315,PrxWPData D109
    315,AL A500
    315,ALData D501
    315,DtTm A600
    315,DtTmData D600
    315,Posn A700
    315,PosnData D700
    315,PVT A800
    315,PVTData D800
    315,nospec A601+D601+A900+A902+A903+A904+A907+D907+D908+D909+D910+A914

    419,Link L001
    419,DevCmd A010
    419,WP A100
    419,WPData D108
    419,RT A201
    419,RTHeade D202
    419,RTWPData D108
    419,RTLinkData D210
    419,TR A301
    419,TRHeader D310
    419,TRData D301
    419,Prx N/A
    419,AL A500
    419,ALData D501
    419,DtTm A600
    419,DtTmData D600
    419,Posn A700
    419,PosnData D700
    419,PVT A800
    419,PVTData D800
    419,nospec A900,A902,A903

    421,Link L001
    421,DevCmd A010
    421,WP A100
    421,WPData D110
    421,RT A201
    421,RTHeader D202
    421,RTWPData D110
    421,RTLinkData D210
    421,TR A301
    421,TRHeader D312
    421,TRData D302
    421,Prx A400
    421,PrxWPData D110
    421,AL A500
    421,ALData D501
    421,DtTm A600
    421,DtTmData D600
    421,Posn A700
    421,PosnData D700
    421,PVT A800
    421,PVTData D800
    421,nospec A601+D601+A900+A902+A903+A904+A907+D907+D908+D909+D910+A908+D911+A914+A916+A917+D917+A918+D918

    450,Link L001
    450,DevCmd A010
    450,WP A100
    450,WPData D110
    450,RT A201
    450,RTHeader D202
    450,RTWPData D110
    450,RTLinkData D210
    450,TR A302
    450,TRHeader D311
    450,TRData D304
    450,Prx N/A
    450,AL A500
    450,ALData D501
    450,DtTm A600
    450,DtTmData D600
    450,Posn A700
    450,PosnData D700
    450,PVT A800
    450,PVTData D800
    450,nospec A601+D601+A801+D801+A902+A903+A907+D907+D908+D909+D910+A918+D918+A1000+D1009+A906+D1011+A1002+D1008+A1003+D1003+A1004+D1004+A1005+D1005+A1006+D1006+A1007+D1007+A1008+D1012+A1009+D1013

    532,Link L001
    532,DevCmd A010
    532,WP A100
    532,WPData D110
    532,RT N/A
    532,TR N/A
    532,Prx N/A
    532,AL A500
    532,ALData D501
    532,DtTm A600
    532,DtTmData: D600
    532,Posn A700
    532,PosnData D700
    532,PVT A800
    532,PVTData D800
    532,nospec A601+D601+A802+D802+A900+A902+A903+A904+A905+D900+A907+D907+D908+D909+D910+A908+D911+A913+A916+A917+D917+A918+D918
}

          # must not differ on the Link and DevCmd protocols
          # cannot refer to unknown/unsupported protocols except in
          #  list of "nospec" protocols
array set PSDIFF {
     7  {59 {RTHeader D200} {TR N/A}}
    13  {59 {RTHeader D200} {Prx A400} {PrxData D400}}
    14  {59 {RTHeader D200} {TR N/A} {Prx A400} {PrxData D400}}
    15  {14 {WPData D151} {RTWPData D151} {PrxData D151}}
    22  {13 {WPData D152} {RTWPData D152} {PrxData D152}}
    29  {59 {WPData D101} {RTWPData D101} {Prx A400} {PrxData D101}}
    29+ {29 {WPData D102} {RTWPData D102} {PrxData D102}}
    39  {59 {WPData D151} {RTWPData D151}}
    45  {59 {WPData D152} {RTWPData D152}}
    48  {59 {WPData D154} {RTWPData D154} {ALData D501}}
    49  {29 {ALData D501}}
    50  {45 {ALData D501}}
    71  {59 {WPData D155} {RTWPData D155} {ALData D501}}
    72  {71 {WPData D104} {RTWPData D104}}
    73  {71 {WPData D103} {RTWPData D103}}
    77  {59 {Prx A400} {PrxData D400} {ALData D501}}
    77+ {73 {Prx A400} {PrxData D403}}
   130  {111 {RTHeader D202}}
   136  {177 {nospec A802+D802+A900+A902+A903}}
   111+ {111 {WPData D109} {RTWPData D109} {PrxWPData D109}}
   112  {59 {WPData D152} {RTWPData D152} {ALData D501}}
   155  {145 {nospec A900+A902+A903+A904}}
   197  {177 {Prx N/A}}
   256  {248 {nospec A802}}
   264  {291 {nospec T001+A802+D802+A900+A902+A903}}
   289+ {289 {nospec A601+D601+A900+A902+A903+A904+A907+D908+D909+D910+A914+A1010+A1011}}
   411  {419 {nospec A802+D802+A900+A902+A903}}
   484  {450 {AL N/A} {nospec A601+D601+A902+A903+A907+D908+D908+D909+D910+A1000+D1009+A906+D1011+A1000+D1009+A1002+D1008+A1003+D1003+A1004+D1004+A1005+D1005+A1006+D1006+A1007+D1007+A1008+D1012+A1009+D1013}}
   484+ {450 {nospec A601+D601+A801+D801+A902+A903+A907+D908+D908+D909+D910+A918+D918+A1000+D1009+A906+D1015+A1002+D1008+A1003+D1003+A1004+D1004+A1005+D1005+A1006+D1006+A1007+D1007+A1008+D1012+A1009+D1013+A1013+D1014}}
}

## descriptions, positions in Garmin structures of GPSMan data
#   normally the suffixes of each data array name, but see
#   the corresponding proc Conv${wh}Data (garmin.tcl)

array set DATAFOR {
    D100,ns {Name Posn Commt}
    D100,ps {0 1 3}

    D101,ns {Name Posn Commt Symbol}
    D101,ps {0 1 3 5}

    D102,ns {Name Posn Commt Symbol}
    D102,ps {0 1 3 5}

    D103,ns {Name Posn Commt Symbol DispOpt}
    D103,ps {0 1 3 4 5}

    D104,ns {Name Posn Commt Symbol DispOpt}
    D104,ps {0 1 3 5 6}

    D105,ns {Posn Symbol Name}
    D105,ps {0 1 2}

    D106,ns {Posn Symbol Name}
    D106,ps {2 3 4}

    D107,ns {Name Posn Commt Symbol DispOpt}
    D107,ps {0 1 3 4 5}

    D108,ns {DispOpt Symbol Posn Alt Name Commt}
    D108,ps {2 4 6 7 12 13}

    D109,ns {DispOpt Symbol Posn Alt Name Commt}
    D109,ps {2 4 6 7 13 14}

    D110,ns {DispOpt Symbol Posn Alt Name Commt}
    D110,ps {2 4 6 7 16 17}

    D150,ns {Name Posn Alt Commt}
    D150,ps {0 3 4 8}

    D151,ns {Name Posn Commt Alt}
    D151,ps {0 1 3 8}

    D152,ns {Name Posn Commt Alt}
    D152,ps {0 1 3 8}

    D154,ns {Name Posn Commt Alt Symbol}
    D154,ps {0 1 3 8 12}

    D155,ns {Name Posn Commt Alt Symbol DispOpt}
    D155,ps {0 1 3 8 12 13}

    D310,ns {Colour Name}
    D310,ps {1 2}

    D311,ns Name
    D311,ps 0

    D312,ns {Colour Name}
    D312,ps {1 2}

    D500,ns {week datatime clockc1 clockc2 ecc sqrta mnanom argprgee
             rightasc rtrightasc inclin}
    D500,ps {0 1 2 3 4 5 6 7 8 9 10}

    D501,ns {week datatime clockc1 clockc2 ecc sqrta mnanom argprgee
             rightasc rtrightasc inclin health}
    D501,ps {0 1 2 3 4 5 6 7 8 9 10 11}

    D550,ns {svid week datatime clockc1 clockc2 ecc sqrta mnanom argprgee
             rightasc rtrightasc inclin}
    D550,ps {0 1 2 3 4 5 6 7 8 9 10 11}

    D551,ns {svid week datatime clockc1 clockc2 ecc sqrta mnanom argprgee
             rightasc rtrightasc inclin health}
    D551,ps {0 1 2 3 4 5 6 7 8 9 10 11 12}

    D906,ns {Start Dur Dist BegPosn EndPosn Cals TRIx}
    D906,ps {0 1 2 3 4 5 6}
}

## colours: names (as in rgb.tcl) ordered as in a C enumeration according to
#   Garmin value, and name of global variable containing default value

array set GARMINCOLOURS {
    D310 {black darkred darkgreen darkyellow darkblue darkmagenta darkcyan
          lightgray darkgray red green yellow blue magenta cyan white
          default}
    D310,dvar DEFTTRCOLOUR
    D312 {black darkred darkgreen darkyellow darkblue darkmagenta darkcyan
          lightgray darkgray red green yellow blue magenta cyan white
	  transparent default}
    D312,dvar DEFTTRCOLOUR
}

## hidden attributes:
#   names, types, default values, positions in Garmin structures,
#   constraints of hidden attributes and (possibly) preprocessing info
#   and formatting info (see proc HiddenFormatVal)

 # positions must be in increasing order!
 # constraints assume that all attributes have been assigned to variables
 #  with the same name

array set HIDDENFOR {
    D106,ns {class subclass lnk_ident}
    D106,ts {byte bytes=13 string}
    D106,vs {0 0 ""}
    D106,ps {0 1 5}
    D106,cs { { if { $class==0 } { lappend undef subclass } } }
    D106,fm {{class enumd {user non_user}}}

    D107,ns {colour}
    D107,ts {byte}
    D107,vs {0}
    D107,ps {7}
    D107,cs {}
    D107,fm {{colour enum {default red green blue}}}

    D108,ns {class colour attrs subclass depth state country facility
	city addr int_road}
    D108,ts {byte byte byte bytes=18 float charray=2 charray=2
	string string string string}
    D108,vs {0 255 96
	"0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255"
	1.0e25 "" "" "" "" "" ""}
    D108,ps {0 1 3 5 8 10 11 14 15 16 17}
    D108,cs {
	{ if { $class==0 || $class>0x46 } { lappend undef city facility } }
	{ if { $class<0x80 } { lappend undef subclass } }
	{ if { $class!=0x83 } { lappend undef addr } }
	{ if { $class!=0x82 } { lappend undef int_road } }
    }
    D108,fm {{class envals {{0 user} {0x40 avn_airport} {0x41 avn_inters}
                            {0x42 avn_NDB} {0x43 avn_VOR}
			    {0x44 avn_airp_rway} {0x45 avn_airp_int}
			    {0x46 avn_airp_NDB} {0x80 map_pt}
			    {0x81 map_area} {0x82 map_int}
			    {0x83 map_addr} {0x84 map_line}}}
	     {colour enumd {black dark_red dark_green dark_yellow dark_blue
			    dark_magenta dark_cyan light_gray dark_gray
			    red green yellow blue magenta cyan white default}}}

    D109,ns {dtyp class colour attrs subclass depth state country ete facility
	city addr int_road}
    D109,ts {byte byte byte byte bytes=18 float charray=2 charray=2
	longword string string string string}
    D109,vs {1 0 0x1f 0x70
	"0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255"
	1.0e25 "" "" 0xffffffff "" "" "" ""}
    D109,ps {0 1 2 3 5 8 10 11 12 15 16 17 18}
    D109,cs {
	{ if { $class==0 || $class>0x46 } { lappend undef city facility } }
	{ if { $class<0x80 } { lappend undef subclass } }
	{ if { $class!=0x83 } { lappend undef addr } }
	{ if { $class!=0x82 } { lappend undef int_road } }
    }
    D109,pp {{colour &0x1f}}
    D109,fm {{class envals {{0 user} {0x40 avn_airport} {0x41 avn_inters}
                            {0x42 avn_NDB} {0x43 avn_VOR}
			    {0x44 avn_airp_rway} {0x45 avn_airp_int}
			    {0x46 avn_airp_NDB} {0x80 map_pt}
			    {0x81 map_area} {0x82 map_int}
			    {0x83 map_addr} {0x84 map_line}}}
	     {colour enumd {black dark_red dark_green dark_yellow dark_blue
			    dark_magenta dark_cyan light_gray dark_gray
			    red green yellow blue magenta cyan white default}}}

    D110,ns {dtyp class colour attrs subclass depth state country ete temp
	     time cat facility city addr int_road}
    D110,ts {byte byte byte byte bytes=18 float charray=2 charray=2
	     longword float longword int string string string string}
    D110,vs {1 0 0 0x80
	"0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255"
	1.0e25 "" "" 0xffffffff 1.0e25 0xffffffff 0 "" "" "" ""}
    D110,ps {0 1 2 3 5 8 10 11 12 13 14 15 18 19 20 21}
    D110,cs {
	{ if { $class==0 || $class>0x46 } { lappend undef city facility } }
	{ if { $class<0x80 } { lappend undef subclass } }
	{ if { $class!=0x83 } { lappend undef addr } }
	{ if { $class!=0x82 } { lappend undef int_road } }
    }
    D110,pp {{colour &0x1f}}
    D110,fm {{class envals {{0 user} {0x40 avn_airport} {0x41 avn_inters}
                            {0x42 avn_NDB} {0x43 avn_VOR}
			    {0x44 avn_airp_rway} {0x45 avn_airp_int}
			    {0x46 avn_airp_NDB} {0x80 map_pt}
			    {0x81 map_area} {0x82 map_int}
			    {0x83 map_addr} {0x84 map_line}}}
	     {colour enumd {black dark_red dark_green dark_yellow dark_blue
			    dark_magenta dark_cyan light_gray dark_gray
			    red green yellow blue magenta cyan white
		            transparent}}}

    D150,ns {country class city state facility}
    D150,ts {charray=2 byte charray=24 charray=2 charray=30}
    D150,vs {"" 4 "" "" ""}
    D150,ps {1 2 5 6 7}
    D150,cs {
	{ if { $class==4 } { lappend undef city state country facility } }
    }
    D150,fm {{class enum {avn_airport avn_inters avn_NDB avn_VOR user
                          avn_airp_rway avn_airp_int locked}}}

    D151,ns {facility city state country class}
    D151,ts {charray=30 charray=24 charray=2 charray=2 byte}
    D151,vs {"" "" "" "" 2}
    D151,ps {5 6 7 9 11}
    D151,cs {
	{ if { $class==2 } { lappend undef city state country facility } }
    }
    D151,fm {{class enum {avn_airport avn_VOR user locked}}}

    D152,ns {facility city state country class}
    D152,ts {charray=30 charray=24 charray=2 charray=2 byte}
    D152,vs {"" "" "" "" 4}
    D152,ps {5 6 7 9 11}
    D152,cs {
	{ if { $class==4 } { lappend undef city state country facility } }
    }
    D152,fm {{class enum {avn_airport avn_inters avn_NDB avn_VOR user locked}}}

    D154,ns {facility city state country class}
    D154,ts {charray=30 charray=24 charray=2 charray=2 byte}
    D154,vs {"" "" "" "" 4}
    D154,ps {5 6 7 9 11}
    D154,cs {
	{ if { $class==4 } { lappend undef city state country facility } }
    }
    D154,fm {{class enum {avn_airport avn_inters avn_NDB avn_VOR user
                          avn_airp_rway avn_airp_int avn_airp_NDB user_symbol
                          locked}}}

    D155,ns {facility city state country class}
    D155,ts {charray=30 charray=24 charray=2 charray=2 byte}
    D155,vs {"" "" "" "" 4}
    D155,ps {5 6 7 9 11}
    D155,cs {
	{ if { $class==4 } { lappend undef city state country facility } }
    }
    D155,fm {{class enum {avn_airport avn_inters avn_NDB avn_VOR user locked}}}

    D210,ns {class subclass}
    D210,ts {word bytes=18}
    D210,vs {0 "0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255"}
    D210,ps {0 1}
    D210,cs {
	{ if { $class==3 || $class==0xff } { lappend undef subclass } }
    }
    D210,fm {{class enum {line link net direct snap}}}

    D310,ns {display}
    D310,ts {boolean}
    D310,vs {0}
    D310,ps {0}
    D310,cs {}
    D310,fm {{display enumd {no  yes}}}

    D312,ns {display}
    D312,ts {boolean}
    D312,vs {0}
    D312,ps {0}
    D312,cs {}
    D312,fm {{display enumd {no  yes}}}
}

# no longer used hidden attributes
#   type, name in FATTRPAIRS array (see files.tcl), and
#   conversion code from Garmin value to GPSMan value

 # conversion code assumes that
 #  - each attribute value have been assigned to a variable with same name
 #  as the attribute
 #  - each such variable is set to the converted value
 #  - the variable $default has been assigned to the default value

array set OLDHIDDENFOR {
    D310:colour {byte colour
	{ set colour [FromGarminColour D310 $colour] }
    }
}

### PVT status for D800

array set GarminPVTStatus {
    0     error
    1     _
    2     2D
    3     3D
    4     2D-diff
    5     3D-diff
}

### Simple Text Output Protocol

set SimpleTextBegs "1 3 5 7 9 11 13 14 16 21 22 25 30 31 34 35 40 \
	41 45 46 50 51"
set SimpleTextEnds "2 4 6 8 10 12 13 15 20 21 24 29 30 33 34 39 40 \
	44 45 49 50 54"

array set SimpleTextPStatus {
    _  _
    d  2D-diff
    D  3D-diff
    g  2D
    G  3D
    S  simul
}

