#
#  gpsman --- GPS Manager: a manager for GPS receiver data
#
#  Copyright (c) 2004 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:  22 November 2004
#

# 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

   # 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
}

   # application protocol categories
array set PROTCAT {
    A010  DevCmd
    A011  DevCmd
    A100  WP
    A200  RT
    A201  RT
    A300  TR
    A301  TR
    A302  TR
    A400  Prx
    A500  AL
    A600  DtTm
    A601  nospec
    A650  FlightBook
    A700  Posn
    A800  PVT
    A802  nospec
    A900  nospec
    A901  nospec
    A902  nospec
    A903  nospec
    A904  nospec
    A906  LAP
}

   # protocol requirements
array set PROTREQ {
    N/A   ""
    P000  ""
    L000  ""
    L001  ""
    L002  ""
    A010  ""
    A011  ""
    A100  WPData
    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
    A802  D?
    A900  ""
    A901  D?
    A902  ""
    A903  ""
    A904  ""
    A906  LAPData
}

   # Basic Link Protocol
set PID(ACK) 6  ; set RPID(6) ACK
set PID(NAK) 21 ; set RPID(21) NAK
set PID(PArray) 253 ; set RPID(253) PArray
set PID(PrdReq) 254 ; set RPID(254) PrdReq
set PID(PrdData) 255 ; set RPID(255) PrdData

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

   # 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}}
set PSPDEF(L002) {{ALData 4} {CmdData 11} {XfrCmpl 12} {DtTmData 20}
                  {PosnData 24} {PrxWPData 27} {Records 35} {RTHeader 37}
                  {RTWPData 39} {WPData 43}}

    # 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}}
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

array set PDTYPE {
    PArray  starray=char,word
    PrdReq  ignored
    PrdData  {int int string 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}
    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}
    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}
    D802  nospec
    D901  nospec
    D906  {longword longword float semicircle semicircle word byte byte}
}

## 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
    "GPS 12 4.58" 138
    "eTrex Summit"  141
    "GPSMAP 196" 145
    "StreetPilot 3" 151
    "eTrex Venture/Mariner"  154
    "GPS 5"  155
    "eTrex Euro"  156
    "eTrex Vista" 169
    "GPS 76" 173
    "GPSMAP 76" 177
    "eTrex Legend" 179
    "GPSMAP 76S" 194
    "Rino 110"   197
    "Rino 120"   209
    "GPS 72" 247
    "Geko 201" 248
    "Geko 301" 256
    "Forerunner" 282
    "GPSmap 276C" 285
    "GPSMap60C" 291
    "ForeTrex" 314
}

    # 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
    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"
    247  "GPS 72"
    248  "Geko 201"
    256  "Geko 301"
    282  "Forerunner"
    285  "GPSmap 276C"
    291  "GPSMap60C"
    314  "ForeTrex"
}

# 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

      # 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+}}
}

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
    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
    247  see=116
    248  array
    256  diff
    282  array
    285  see=291
    291  array
    314  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

    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

    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

    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

    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
}

          # must not differ on the Link and DevCmd 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}}
   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}}
}

## 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 {0 2}

    D311,ns Name
    D311,ps 0

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

    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}
    D310,dvar DEFTTRCOLOUR
    D312 {black darkred darkgreen darkyellow darkblue darkmagenta darkcyan
          lightgray darkgray red green yellow blue magenta cyan white
	  transparent}
    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 0xfffffffff 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 {1}
    D310,cs {}
    D310,fm {{display enumd {no  yes}}}

    D312,ns {display}
    D312,ts {boolean}
    D312,vs {0}
    D312,ps {1}
    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
}

