Project

General

Profile

New Model #10109 » kg1000gplus b1.0.py

Wouxun KG-1000G Plus Beta 1.0 Driver - Mel Terechenok, 11/12/2022 12:01 AM

 
1
# melvin.terechenok@gmail.com
2
# modify for KG-1000G+  using KG-UV980P KG-935G, KG-UV8H, KG-UV920P drivers as resources
3

    
4
# Copyright 2019 Pavel Milanes CO7WT <pavelmc@gmail.com>
5
#
6
# Based on the work of Krystian Struzik <toner_82@tlen.pl>
7
# who figured out the crypt used and made possible the
8
# Wuoxun KG-UV8D Plus driver, in which this work is based.
9
#
10
# This program is free software: you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation, either version 3 of the License, or
13
# (at your option) any later version.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22

    
23
"""Wouxun KG-1000G+ radio management module"""
24

    
25
from pickle import FALSE, TRUE
26
import time
27
import os
28
import logging
29

    
30
from chirp import util, chirp_common, bitwise, memmap, errors, directory
31
from chirp.settings import RadioSetting, RadioSettingGroup, \
32
    RadioSettingValueBoolean, RadioSettingValueList, \
33
    RadioSettingValueInteger, RadioSettingValueString, \
34
    RadioSettingValueFloat, RadioSettingValueMap, RadioSettings
35

    
36

    
37
LOG = logging.getLogger(__name__)
38

    
39
CMD_ID = 128    # \x80
40
CMD_END = 129   # \x81
41
CMD_RD = 130    # \x82
42
CMD_WR = 131    # \x83
43

    
44
MEM_VALID = 0x00
45
TX_BLANK = 0x40
46
RX_BLANK = 0x80
47

    
48
CHARSET_NUMERIC = "0123456789"
49
CHARSET = "0123456789" + \
50
          ":;<=>?@" + \
51
          "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + \
52
          "[\]^_`" + \
53
          "abcdefghijklmnopqrstuvwxyz" + \
54
          "{|}~\x4E" + \
55
          " !\"#$%&'()*+,-./"
56

    
57
SCANNAME_CHARSET = "0123456789" + \
58
          ":;<=>?@" + \
59
          "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + \
60
          "[\]^_`" + \
61
          "abcdefghijklmnopqrstuvwxyz" + \
62
          "{|}~\x4E" + \
63
          " !\"#$%&'()*+,-./"
64

    
65
MUTE_MODE_MAP = [('QT',      0b01),
66
                 ('QT*DTMF', 0b10),
67
                 ('QT+DTMF', 0b11)]
68
STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 30.0, 50.0, 100.0]
69
STEP_LIST = [str(x) for x in STEPS]
70
SQL_LIST = [int(i) for i in range(0, 10)]
71
M_POWER_MAP = [('1 = 20W', 1),
72
               ('2 = 10W', 2)]
73
ROGER_LIST = ["Off", "BOT", "EOT", "Both"]
74
VOICE_LIST = ["Off", "Chinese", "English"]
75
SC_REV_MAP = [('Timeout (TO)',  1),
76
              ('Carrier (CO)',  2),
77
              ('Stop (SE)',     3)]
78
TOT_MAP = [('%d min' % i, int('%02d' % i, 10)) for i in range(1, 61)]
79
TOA_LIST = ["Off", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"]
80
RING_LIST = ["Off", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"]
81
DTMF_ST_LIST = ["Off", "DTMF", "ID", "DTMF+ID"]
82
PTT_ID_MAP = [('Off', 0),
83
              ('BOT',  1),
84
              ('EOT',  2),
85
              ('Both', 3)]
86
BACKLIGHT_LIST = ["Off", "Red", "Orange", "Green"]
87
SPEAKER_MAP = [('RADIO',   1),
88
               ('MIC',   2),
89
               ('BOTH', 3)]
90
RPT_MODE_MAP = [("OFF", 0),
91
                ("RPT-RX", 3),
92
                ("RPT-TX", 4)]
93
APO_TIME_LIST = ["Off", "30", "60", "90", "120", "150"]
94
ALERT_MAP = [('1750', 1),
95
             ('2100', 2),
96
             ('1000', 3),
97
             ('1450', 4)]
98
FAN_MODE_LIST = ["TX", "Hi-Temp/TX", "Always"]
99
SCAN_GROUP_LIST = ["All"] + ["%s" % x for x in range(1, 11)]
100
WORKMODE_MAP = [('Freq',      1),
101
                ('Ch-Num',   2),
102
                ('Ch-Freq', 3),
103
                ('Ch-Name',  4)]
104
VFOBAND_MAP = [("150M",0),
105
               ("450M",1),
106
            #    ("20M",2),
107
               ("50M",3),
108
               ("350M",4),
109
               ("850M",5)]              
110
AB_LIST = ["A", "B"]
111
POWER_MAP = [('Low', 0),
112
             ('Med', 1),
113
             ('Med2', 2),
114
             ('High', 3)]
115
BANDWIDTH_MAP = [('Narrow', 1),
116
                 ('Wide',  0)]
117
SCRAMBLER_LIST = ["Off", "1", "2", "3", "4", "5", "6", "7", "8"]
118
ANS_LIST = ["Off", "Normal", "Strong"]
119
DTMF_TIMES = [str(x) for x in range(80, 501, 20)]
120
DTMF_INTERVALS = [str(x) for x in range(60, 501, 20)]
121
ROGER_TIMES = [str(x) for x in range(20, 1001, 20)]
122
PTT_ID_DELAY_MAP = [(str(x), x/100) for x in range(100, 1001, 100)]
123
ROGER_INTERVALS = ROGER_TIMES
124
TONE_MAP = [('Off', 0x0000)] + \
125
           [('%.1f' % tone, int(tone * 10)) for tone in chirp_common.TONES] + \
126
           [('DN%d' % tone, int(0x8000 + tone))
127
               for tone in chirp_common.DTCS_CODES] + \
128
           [('DI%d' % tone, int(0xC000 + tone))
129
               for tone in chirp_common.DTCS_CODES]
130
DUPLEX_LIST = ["Off", "Plus", "Minus"]
131
SC_QT_MAP = [("Rx", 1), ("Tx", 2),
132
             ("Tx/Rx", 3)]
133
HOLD_TIMES = ["Off"] + ["%s" % x for x in range(100, 5001, 100)]
134
PF1_SETTINGS = ["OFF", "Reverse", "Pri-Sel", "Pri-Scan", "Squelch", "TX PWR", "Scan", "Scan CTCSS",
135
           "Scan DCS", "FM Radio", "Weather", "Ch-Add", "W-N", "TDR", "WORKMODE", 
136
           "Band", "Repeater", "Lock", "Monitor"]
137
ABR_LIST = ["Always", "1", "2", "3", "4", "5", "6", "7", "8",
138
            "9", "10", "11", "12", "13", "14", "15", "16", "17",
139
            "18", "19", "20", "Off"]
140
KEY_LIST = ["OFF", "Reverse", "Pri-Sel", "Pri-Scan", "Squelch", "TX PWR", "Scan", "Scan CTCSS",
141
           "Scan DCS", "FM Radio", "Weather", "Ch-Add", "W-N", "TDR", "WORKMODE", 
142
           "Band", "Repeater", "Lock", "Monitor"]
143
RC_POWER_LIST = ["RC Stop", "RC Open"]
144
ACTIVE_AREA_LIST = ["Area A - Left", "Area B - Right"]
145
TDR_LIST = ["TDR ON", "TDR OFF"]
146
PRI_CH_SCAN_LIST = ["Off", "ON-Stby", "On-Always"]
147

    
148
# memory slot 0 is not used, start at 1 (so need 1000 slots, not 999)
149
# structure elements whose name starts with x are currently unidentified
150

    
151
_MEM_FORMAT = """
152
    #seekto 0x004c;
153
    struct {
154
        u24 mode_psw;
155
        u8  xunk04F;
156
        u8  display_name[8];
157
    } oem;
158

    
159
    #seekto 0x0060;
160
    struct {
161
        u16    limit_144M_ChA_rx_start;
162
        u16    limit_144M_ChA_rx_stop;    
163
        u16    limit_70cm_rx_start;
164
        u16    limit_70cm_rx_stop;    
165
        u16    limit_10m_rx_start;
166
        u16    limit_10m_rx_stop;    
167
        u16    limit_6m_rx_start;
168
        u16    limit_6m_rx_stop;    
169
        u16    limit_350M_rx_start;
170
        u16    limit_350M_rx_stop;    
171
        u16    limit_850M_rx_start;
172
        u16    limit_850M_rx_stop;    
173
        u16    limit_144M_ChA_tx_start;
174
        u16    limit_144M_ChA_tx_stop;    
175
        u16    limit_70cm_tx_start;
176
        u16    limit_70cm_tx_stop;    
177
        u16    limit_10m_tx_start;
178
        u16    limit_10m_tx_stop;    
179
        u16    limit_6m_tx_start;
180
        u16    limit_6m_tx_stop;    
181
        u16    limit_144M_ChB_rx_start;
182
        u16    limit_144M_ChB_rx_stop;
183
    } bandlimits;
184

    
185

    
186
    #seekto 0x0740;
187
    struct {
188
        u16    FM_radio1;
189
        u16    FM_radio2;
190
        u16    FM_radio3;
191
        u16    FM_radio4;
192
        u16    FM_radio5;
193
        u16    FM_radio6;
194
        u16    FM_radio7;
195
        u16    FM_radio8;
196
        u16    FM_radio9;
197
        u16    FM_radio10;
198
        u16    FM_radio11;
199
        u16    FM_radio12;
200
        u16    FM_radio13;
201
        u16    FM_radio14;
202
        u16    FM_radio15;
203
        u16    FM_radio16;
204
        u16    FM_radio17;
205
        u16    FM_radio18;
206
        u16    FM_radio19;
207
        u16    FM_radio20;
208
        u16    FM_radio21;
209
        u16    FM_radio22;
210
        u8  x76c_pad[196];
211
        u32  vfofreq1;     // 0x0830
212
        u32  vfoofst1;
213
        u16  txtone1;
214
        u16  rxtone1;
215
        u8  xunk83C_1:3,
216
            mute1:2,
217
            xunk83C_2:3;
218
        u8  xunk83d_1:1,
219
            xunk83d_2:1,
220
            xunk83d_3:1,
221
            power1:2,
222
            am_mode1:1,
223
            xunk83d_7:1,
224
            narrow1:1;
225
        u8  xunk83e:6,
226
            shft_dir1:2;
227
        u8  xunk83F:3,
228
            compander1:1,
229
            scrambler1:4;
230
        u32  vfofreq2;
231
        u32  vfoofst2;
232
        u16  txtone2;
233
        u16  rxtone2;
234
        u8  xunk84C_1:3,
235
            mute2:2,
236
            xunk84C_2:3;
237
        u8  xunk84d_1:1,
238
            xunk84d_2:1,
239
            xunk84d_3:1,
240
            power2:2,
241
            am_mode2:1,
242
            xunk84d_7:1,
243
            narrow2:1;
244
        u8  xunk84e:6,
245
            shft_dir2:2;
246
        u8  xunk84F:3,
247
            compander2:1,
248
            scrambler2:4;
249
        u32  vfofreq3;
250
        u32  vfoofst3;
251
        u16  txtone3;
252
        u16  rxtone3;
253
        u8  xunk85C_1:3,
254
            mute3:2,
255
            xunk85C_2:3;
256
        u8  xunk85d_1:1,
257
            xunk85d_2:1,
258
            xunk85d_3:1,
259
            power3:2,
260
            am_mode3:1,
261
            xunk85d_7:1,
262
            narrow3:1;
263
        u8  xunk85e:6,
264
            shft_dir3:2;
265
        u8  xunk85F:3,
266
            compander3:1,
267
            scrambler3:4;
268
        u32  vfofreq4;
269
        u32  vfoofst4;
270
        u16  txtone4;
271
        u16  rxtone4;
272
        u8  xunk86C_1:3,
273
            mute4:2,
274
            xunk86C_2:3;
275
        u8  xunk86d_1:1,
276
            xunk86d_2:1,
277
            xunk86d_3:1,
278
            power4:2,
279
            am_mode4:1,
280
            xunk86d_7:1,
281
            narrow4:1;
282
        u8  xunk86e:6,
283
            shft_dir4:2;
284
        u8  xunk86F:3,
285
            compander4:1,
286
            scrambler4:4;
287
        u32  vfofreq5;
288
        u32  vfoofst5;
289
        u16  txtone5;
290
        u16  rxtone5;
291
        u8  xunk87C_1:3,
292
            mute5:2,
293
            xunk87C_2:3;
294
        u8  xunk87d_1:1,
295
            xunk87d_2:1,
296
            xunk87d_3:1,
297
            power5:2,
298
            am_mode5:1,
299
            xunk87d_7:1,
300
            narrow5:1;
301
        u8  xunk87e:6,
302
            shft_dir5:2;
303
        u8  xunk87F:3,
304
            compander5:1,
305
            scrambler5:4;
306
        u32  vfofreq6;
307
        u32  vfoofst6;
308
        u16  txtone6;
309
        u16  rxtone6;
310
        u8  xunk88C_1:3,
311
            mute6:2,
312
            xunk88C_2:3;
313
        u8  xunk88d_1:1,
314
            xunk88d_2:1,
315
            xunk88d_3:1,
316
            power6:2,
317
            am_mode6:1,
318
            xunk88d_7:1,
319
            narrow6:1;
320
        u8  xunk88e:6,
321
            shft_dir6:2;
322
        u8  xunk8F:3,
323
            compander6:1,
324
            scrambler6:4;
325
        u32  vfofreq7;
326
        u32  vfoofst7;
327
        u16  txtone7;
328
        u16  rxtone7;
329
        u8  xunk89C_1:3,
330
            mute7:2,
331
            xunk89C_2:3;
332
        u8  xunk89d_1:1,
333
            xunk89d_2:1,
334
            xunk89d_3:1,
335
            power7:2,
336
            am_mode7:1,
337
            xunk89d_7:1,
338
            narrow7:1;
339
        u8  xunk89e:6,
340
            shft_dir7:2;
341
        u8  xunk89F:3,
342
            compander7:1,
343
            scrambler7:4;
344
        u8  x8a0;
345
        u16  vfochan_a;
346
        u8  x8a3;
347
        u16  vfochan_b;
348
        u16  pri_ch;
349
        u8  x8a8;
350
        u8  x8a9;
351
        u8  scan_a_act;
352
        u8  scan_b_act;
353
        u8  m_pwr;
354
        u8  hold_time_rpt;
355
        u8  spk_cont;
356
        u8  x8af;
357
        u8  rc_power;
358
        u8  voice;
359
        u8  tot;
360
        u8  toa;
361
        u8  roger;
362
        u8  sc_rev;
363
        u8  dtmfsf;
364
        u8  ptt_id;
365
        u8  ring;
366
        u8  ani_sw;
367
        u8  rc_sw;
368
        u8  alert;
369
        u8  bcl_a;
370
        u8  prich_sw;
371
        u8  x8bE;
372
        u8  ptt_id_dly; 
373
        u8  menu;
374
        u8  x8c1;
375
        u8  beep;
376
        u8  key_lock;
377
        u8  x8c4;
378
        u8  tx_led;
379
        u8  wt_led;
380
        u8  rx_led;
381
        u8  act_area;
382
        u8  vfomode_a;
383
        u8  vfomode_b;
384
        u8  vfosquelch_a;
385
        u8  vfosquelch_b;
386
        u8  vfostep_a;
387
        u8  vfostep_b;
388
        u8  tdr_off;
389
        u8  rpt_spk; //x8d0
390
        u8  rpt_ptt;
391
        u8  autolock;
392
        u8  apo_time;
393
        u8  low_v;
394
        u8  fan;
395
        u8  rpt_set_model;
396
        u8  pf1_set;
397
        u8  auto_am;
398
        u8  dtmf_time;
399
        u8  dtmf_int;
400
        u8  bcl_b;
401
        u8  rpt_tone;
402
        u8  sc_qt;
403
        u8  vfoband_a;
404
        u8  x8dF;
405
        u24  ani_edit;
406
        u8  x8e3;
407
        u24  mcc_edit;
408
        u8  x8e7;
409
        u24  scc_edit;
410
        u8  x8eB;
411
        u24  ctrl_edit;
412
        u8  x8eF;
413
        u8  KeyA;
414
        u8  KeyB;
415
        u8  KeyC;
416
        u8  ABR;
417
        u8  x8f4;
418
        u8  x8f5;
419
        u8  KeyD;
420
        u8  x8f7;
421
        u8  x8f8;
422
        u8  x8f9;
423
        u8  x8fA;
424
        u8  x8fB;
425
        u8  x8fC;
426
        u8  x8fD;
427
        u8  x8fE;
428
        u8  x8fF;
429
        u16  FM_radio_cur_freq;
430
        u8  x902;
431
        u8  scan_det;
432
        u8  x904;
433
        u8  thr_vol_tx;
434
        u16  thr_vol_lvl;
435
        u8  x908;
436
        u8  x909;
437
        u8  x90A;
438
        u8  x90B;
439
        u8  x90C;
440
        u8  x90D;
441
        u8  x90E;
442
        u8  x90F;
443
        u8  x910pad[48];
444
        u16  scanlower1; // x940
445
        u16  scanupper1;
446
        u16  scanlower2;
447
        u16  scanupper2;
448
        u16  scanlower3;
449
        u16  scanupper3;
450
        u16  scanlower4;
451
        u16  scanupper4;
452
        u16  scanlower5;
453
        u16  scanupper5;
454
        u16  scanlower6;
455
        u16  scanupper6;
456
        u16  scanlower7;
457
        u16  scanupper7;
458
        u16  scanlower8;
459
        u16  scanupper8;
460
        u16  scanlower9;
461
        u16  scanupper9;
462
        u16  scanlower10;
463
        u16  scanupper10;
464
        char  scanname0[8]; // x968
465
        char  scanname1[8];
466
        char  scanname2[8];
467
        char  scanname3[8];
468
        char  scanname4[8];
469
        char  scanname5[8];
470
        char  scanname6[8];
471
        char  scanname7[8];
472
        char  scanname8[8];
473
        char  scanname9[8];
474
        char  scanname10[8];
475
     } settings;
476

    
477

    
478
    #seekto 0x09f0;
479
    struct {
480
        u32     rxfreq;
481
        u32     txfreq;
482
        u16     txtone;
483
        u16     rxtone;
484
        u8      unknown1:3,
485
                mute_mode:2,
486
                unknown2:3;
487
        u8      named:1,
488
                scan_add:1,
489
                extra_power_bit:1,
490
                power:2,
491
                am_mode:1,
492
                unknownbit2:1,
493
                isnarrow:1;
494
        u8      unknown3:6,
495
                Unknown4_shft_dir:2;
496
        u8      unknown5:3,
497
                compander:1
498
                scrambler:4;
499
    } memory[1000];
500

    
501
    #seekto 0x48f8;
502
    struct {
503
        u8    name[8];
504
    } names[1000];
505

    
506
    #seekto 0x6fff;
507
    u8          valid[1000];
508
    """
509

    
510
def _freq_decode(in_freq, bytes=4):
511
    out_freq = 0
512
    for i in range(bytes*2):
513
        out_freq += (in_freq & 0xF) * (10 ** i)
514
        in_freq = in_freq >> 4
515
    if bytes == 4:
516
        return out_freq * 10
517
    elif bytes == 2:
518
        return out_freq * 100000
519

    
520

    
521
def _freq_encode(in_freq, bytes=4):
522
    if bytes == 4:
523
        return int('%08d' % (in_freq / 10), 16)
524
    elif bytes == 2:
525
        return int('%04d' % (in_freq / 100000), 16)
526

    
527
def _oem_str_decode(in_str):
528
    LOG.debug("decode OEM Input String = %s", in_str)
529
    out_str = ''
530
    stopchar = FALSE
531
    for c in in_str:
532
        # if c !=0x50 and stopchar==FALSE:
533
# 1000G+ character mapping starts with P = 32 and O = 127
534
        if 127 >= c >=80:
535
            LOG.debug(" 127>=c>=80 c = %s", c )
536
            out_str+= chr(c-48)
537
        elif 32 <= c < 80: 
538
            LOG.debug(" 32<=c<80 c = %s", c )
539
            out_str+= chr(c+48)
540
        # if chr(c-48) in chirp_common.CHARSET_ASCII:
541
        #     out_str+= chr(c-48)
542
        # elif chr(c+48) in chirp_common.CHARSET_ASCII: 
543
        #     out_str+= chr(c+48)
544
        else:
545
            out_str+=''
546
            stopchar = TRUE
547
    LOG.debug("decode OEM Ouput String = %s", out_str)
548
    return out_str
549

    
550
def _oem_str_encode(in_str):
551
    out_str = ''
552
    LOG.debug("encode OEM Input String = %s", in_str)
553
    for c in in_str:
554
        if 32 <= ord(c) < 80:
555
            out_str += chr(int(ord(c))+48)
556
        elif 127 >= ord(c) >=80:
557
            out_str += chr(int(ord(c))-48)                
558
    while len(out_str) < 8:
559
        out_str += chr(0x50)
560
    LOG.debug("encode OEM Ouput String = %s", out_str)
561
    return out_str
562

    
563

    
564
def _str_decode(in_str):
565
    out_str = ''
566
    stopchar = FALSE
567
    for c in in_str:
568
        if c !=0x00 and stopchar==FALSE:
569
            if chr(c) in chirp_common.CHARSET_ASCII:
570
                out_str+= chr(c)
571
        else:
572
            out_str+=''
573
            stopchar = TRUE
574
    return out_str
575

    
576

    
577
def _str_encode(in_str):
578
    out_str = ''
579
    for c in in_str:
580
        try:
581
            out_str += chr(ord(c))
582
        except ValueError:
583
            pass
584
    while len(out_str) < 8:
585
        out_str += chr(0x00)
586
    if out_str == "        " or out_str == "":
587
        out_str = "\x00\x00\x00\x00\x00\x00\x00\x00"
588
    return out_str
589

    
590
def _chnum_decode(in_ch):
591
    return int(('%04x' % in_ch)[0:3])
592

    
593

    
594
def _chnum_encode(in_ch):
595
    return int('%03d0' % in_ch, 16)
596

    
597
# Support for the Wouxun KG-1000G+ radio
598
# Serial coms are at 19200 baud
599
# The data is passed in variable length records
600
# Record structure:
601
#  Offset   Usage
602
#    0      start of record (\x7c)
603
#    1      Command (\x80 Identify \x81 End/Reboot \x82 Read \x83 Write)
604
#    2      direction (\xff PC-> Radio, \x00 Radio -> PC)
605
#    3      length of payload (excluding header/checksum) (n)
606
#    4      payload (n bytes)
607
#    4+n+1  checksum - only lower 4 bits of byte sum (% 256) of bytes 1 -> 4+n
608
#
609
# Memory Read Records:
610
# the payload is 3 bytes, first 2 are offset (big endian),
611
# 3rd is number of bytes to read
612
# Memory Write Records:
613
# the maximum payload size (from the Wouxun software) seems to be 66 bytes
614
#  (2 bytes location + 64 bytes data).
615

    
616

    
617

    
618
class KGUV8TRadio(chirp_common.Alias):
619
    VENDOR = "Wouxun"
620
    MODEL = "KG-1000G Plus"
621

    
622

    
623
@directory.register
624
class KG1000GPlusRadio(chirp_common.CloneModeRadio,
625
                  chirp_common.ExperimentalRadio):
626

    
627
    """Wouxun KG-1000G Plus"""
628
    VENDOR = "Wouxun"
629
    MODEL = "KG-1000G Plus"
630
    _model = "KG-UV950R2"
631
    _file_ident = "1000G Plus"
632
    BAUD_RATE = 19200
633

    
634
    POWER_LEVELS = [chirp_common.PowerLevel("L", watts=1.0), 
635
                    chirp_common.PowerLevel("M", watts=20.0), 
636
                    chirp_common.PowerLevel("H", watts=50.0)]
637
    _mmap = ""
638
    ALIASES = [KGUV8TRadio, ]
639

    
640
    def _checksum(self, data):
641
        cs = 0
642
        for byte in data:
643
            cs += ord(byte)
644
        return chr(cs % 256)
645

    
646
    # def _write_record_id(self):
647
	# _header = '\xda\x80\xff\x00\x58'
648
    #     LOG.error("Sent:\n%s" % util.hexprint(_header))
649
	# self.pipe.write(_header)
650

    
651
    def _write_record(self, cmd, payload=None):
652
        # build the packet
653
        _header = '\xda' + chr(cmd) + '\xff'
654

    
655
        _length = 0
656
        if payload:
657
            _length = len(payload)
658

    
659
        # update the length field
660
        _header += chr(_length)
661

    
662
        if payload:
663
            # calculate checksum then add it with the payload
664
            # to the packet and encrypt
665
            crc = self._checksum(_header[1:] + payload)
666
            # Checksum is only the lower 4 bits
667
            crc = chr(ord(crc) & 0xf)
668
            payload += crc
669
            _header += self.encrypt(payload)
670
        else:
671
            # calculate and add encrypted checksum to the packet
672
            crc = self._checksum(_header[1:])
673
            # Checksum is only the lower 4 bits
674
            crc = chr(ord(crc) & 0xf)
675
            _header += self.strxor(crc, '\x57')
676

    
677
        try:
678
            LOG.debug("Sent:\n%s" % util.hexprint(_header))
679
            self.pipe.write(_header)
680
        except Exception, e:
681
            raise errors.RadioError("Failed to communicate with radio: %s" % e)
682

    
683
    def _read_record(self):
684
        # read 4 chars for the header
685
        _header = self.pipe.read(4)
686
        #LOG.debug("header = " % util.hexprint(_header))
687
        if len(_header) != 4:
688
            raise errors.RadioError('Radio did not respond- header length')
689
        _length = ord(_header[3])
690
        _packet = self.pipe.read(_length)
691
        _rcs_xor = _packet[-1]
692
        _packet = self.decrypt(_packet)
693
        _cs = ord(self._checksum(_header[1:] + _packet))
694
        # It appears the checksum is only 4bits
695
        _cs = _cs & 0xf
696
        # read the checksum and decrypt it 
697
        _rcs = ord(self.strxor(self.pipe.read(1), _rcs_xor))
698
        _rcs = _rcs & 0xf
699
        return (_rcs != _cs, _packet)
700

    
701
    def decrypt(self, data):
702
        result = ''
703
        for i in range(len(data)-1, 0, -1):
704
            result += self.strxor(data[i], data[i - 1])
705
        result += self.strxor(data[0], '\x57')
706
        return result[::-1]
707

    
708
    def encrypt(self, data):
709
        result = self.strxor('\x57', data[0])
710
        for i in range(1, len(data), 1):
711
            result += self.strxor(result[i - 1], data[i])
712
        return result
713

    
714
    def strxor(self, xora, xorb):
715
        return chr(ord(xora) ^ ord(xorb))
716

    
717
    # Identify the radio
718
    #
719
    # A Gotcha: the first identify packet returns a bad checksum, subsequent
720
    # attempts return the correct checksum... (well it does on my radio!)
721
    #
722
    # The ID record returned by the radio also includes the
723
    # current frequency range
724
    # as 4 bytes big-endian in 10Hz increments
725
    #
726
    # Offset
727
    #  0:10     Model, zero padded 
728

    
729
    @classmethod
730
    def match_model(cls, filedata, filename):
731
        id = cls._file_ident
732
        return cls._file_ident in filedata[0x426:0x430]
733

    
734
    def _identify(self):
735
        """Do the identification dance"""
736
        for _i in range(0, 3):
737
            LOG.debug("ID try #"+str(_i))
738
            self._write_record(CMD_ID)
739
            _chksum_err, _resp = self._read_record()
740
            if len(_resp) == 0:
741
                raise Exception("Radio not responding")
742
            else:
743
                LOG.debug("Got:\n%s" % util.hexprint(_resp))
744
                LOG.debug("Model received is %s" % _resp[0:10])
745
                LOG.debug("Model expected is %s" % self._model)
746
                if _chksum_err:
747
                    LOG.error("Checksum error: retrying ident...")
748
                    time.sleep(0.100)
749
                    continue
750
                else:
751
                    LOG.debug("checksum passed")
752
                    if _resp[0:8] == self._model[0:8]:
753
                        LOG.debug("Passed identify")
754
                        break
755
                    else:
756
                        LOG.debug("FAILED to identify") 
757
                  
758

    
759
    def _finish(self):
760
        self._write_record(CMD_END)
761

    
762
    def process_mmap(self):
763
        self._memobj = bitwise.parse(_MEM_FORMAT, self._mmap)
764

    
765
    def sync_in(self):
766
        try:
767
            self._mmap = self._download()
768
        except errors.RadioError:
769
            raise
770
        except Exception, e:
771
            raise errors.RadioError("Failed to communicate with radio: %s" % e)
772
        self.process_mmap()
773

    
774
    def sync_out(self):
775
        self._upload()
776

    
777
    # TODO: Load all memory.
778
    # It would be smarter to only load the active areas and none of
779
    # the padding/unused areas. Padding still need to be investigated.
780
    def _download(self):
781
        """Talk to a wouxun KG-1000G Plus and do a download"""
782
        try:
783
            self._identify()
784
            return self._do_download(0, 32768, 64)
785
        except errors.RadioError:
786
            raise
787
        except Exception, e:
788
            LOG.exception('Unknown error during download process')
789
            raise errors.RadioError("Failed to communicate with radio: %s" % e)
790

    
791
    def _do_download(self, start, end, blocksize):
792
        # allocate & fill memory
793
        LOG.debug("Start Download")
794
        image = ""
795
        for i in range(start, end, blocksize):
796
            req = chr(i / 256) + chr(i % 256) + chr(blocksize)
797
            self._write_record(CMD_RD, req)
798
            cs_error, resp = self._read_record()
799
            LOG.debug("Got:\n%s" % util.hexprint(resp))
800

    
801
            if cs_error:
802
                LOG.debug(util.hexprint(resp))
803
                raise Exception("Checksum error on read")
804
            # LOG.debug("Got:\n%s" % util.hexprint(resp))
805
            image += resp[2:]
806
            if self.status_fn:
807
                status = chirp_common.Status()
808
                status.cur = i
809
                status.max = end
810
                status.msg = "Cloning from radio"
811
                self.status_fn(status)
812
        self._finish()
813
        return memmap.MemoryMap(''.join(image))
814

    
815
    def _upload(self):
816
        """Talk to a wouxun KG-1000G Plus and do a upload"""
817
        try:
818
            self._identify()
819
            LOG.debug("Done with Upload Identify")
820
            # self._do_upload(0, 1856, 16)
821
            # LOG.debug("Done with Limits Upload")
822
            # self._do_upload(1856, 32768, 64)
823
            self._do_upload(0, 32768, 64)
824
            LOG.debug("Done with Mem and Settings Upload")
825
            self._finish()
826
        except errors.RadioError:
827
            raise
828
        except Exception, e:
829
            raise errors.RadioError("Failed to communicate with radio: %s" % e)
830
        return
831

    
832
    def _do_upload(self, start, end, blocksize):
833
        LOG.debug("Start of _do_upload")
834
        ptr = start
835
        LOG.debug("ptr = " + str(ptr))
836
        for i in range(start, end, blocksize):
837
            LOG.debug("Start of loop in _do_upload index = "+str(i))
838
            LOG.debug("Start %i End %i Size %i" % (start, end, blocksize))
839
            req = chr(i/ 256) + chr(i % 256)
840
            LOG.debug("REQ")
841
            chunk = self.get_mmap()[ptr:ptr + blocksize]
842
            LOG.debug("CHUNK")
843
            self._write_record(CMD_WR, req + chunk)
844
#            LOG.debug("Upload-- SENT : " % util.hexprint(_sent))
845
            cserr, ack = self._read_record()
846
            LOG.debug("Upload-- CSUM ERROR : " + str(cserr))
847
            LOG.debug("Upload-- RCVD :\n%s " % util.hexprint(ack))
848
            
849
            j = ord(ack[0]) * 256 + ord(ack[1])
850
            if cserr or j != ptr:
851
                raise Exception("Radio did not ack block %i" % ptr)
852
            ptr += blocksize
853
            if self.status_fn:
854
                status = chirp_common.Status()
855
                status.cur = i
856
                status.max = end
857
                status.msg = "Cloning to radio"
858
                self.status_fn(status)
859
        # self._finish()
860

    
861
    def get_features(self):
862
        rf = chirp_common.RadioFeatures()
863
        rf.has_settings = True
864
        rf.has_ctone = True
865
        rf.has_rx_dtcs = True
866
        rf.has_cross = True
867
        rf.has_tuning_step = False
868
        rf.has_bank = False
869
        rf.can_odd_split = True
870
        rf.valid_skips = ["", "S"]
871
        rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"]
872
        rf.valid_cross_modes = [
873
            "Tone->Tone",
874
            "Tone->DTCS",
875
            "DTCS->Tone",
876
            "DTCS->",
877
            "->Tone",
878
            "->DTCS",
879
            "DTCS->DTCS",
880
        ]
881
        rf.valid_modes = ["FM", "NFM", "AM", "NAM"]
882
        rf.valid_power_levels = self.POWER_LEVELS
883
        rf.valid_name_length = 8
884
        rf.valid_duplexes = ["", "-", "+", "split", "off"]
885
#   MRT - Open up channel memory freq range to support RxFreq limit expansion
886
        rf.valid_bands = [(26000000, 299999999),  # supports VHF
887
                          (300000000, 999999999)]  # supports UHF
888

    
889
        rf.valid_characters = chirp_common.CHARSET_ASCII
890
        rf.memory_bounds = (1, 999)  # 999 memories
891
        rf.valid_tuning_steps = STEPS
892
        return rf
893

    
894
    @classmethod
895
    def get_prompts(cls):
896
        rp = chirp_common.RadioPrompts()
897
        rp.experimental = \
898
            ('This driver is experimental and may contain bugs. \n'
899
              'USE AT YOUR OWN RISK  - '
900
              ' SAVE A COPY OF DOWNLOAD FROM YOUR RADIO BEFORE MAKING CHANGES\n'
901
              '\nAll known CPS settings are implemented \n'
902
              '\n Additional settings found only on radio are also included'
903
              '\nMute, Compander and Scrambler are defaulted to '
904
              'QT, OFF , OFF for all channel memories\n'
905
              '\n'
906
              'Modification of Freq Limit Interfaces is done AT YOUR OWN RISK and '
907
              'may affect radio performance and may violate rules, regulations '
908
              'or laws in your jurisdiction.\n'
909
             )
910
        return rp
911

    
912
    def get_raw_memory(self, number):
913
        return repr(self._memobj.memory[number])
914
# MRT - corrected the Polarity decoding to match 1000G Plus implementation
915
# use 0x4000 bit mask for R
916
# MRT - 0x4000 appears to be the bit mask for Inverted DCS tones
917
# MRT - n DCS Tone will be 0x8xxx values - i DCS Tones will
918
# be 0xCxxx values.
919
# MRT - Chirp Uses N for n DCS Tones and R for i DCS Tones
920
# MRT - 1000G Plus encodes DCS tone # in decimal -  NOT OCTAL
921

    
922
    def _get_tone(self, _mem, mem):
923
        def _get_dcs(val):
924
            code = int("%03d" % (val & 0x07FF))
925
            pol = (val & 0x4000) and "R" or "N"
926
            return code, pol
927
# MRT - Modified the function below to bitwise AND with 0x4000
928
# to check for 1000G Plus DCS Tone decoding
929
# MRT 0x8000 appears to be the bit mask for DCS tones
930
        tpol = False
931
# MRT Beta 1.1 - Fix the txtone compare to 0x8000 - was rxtone.
932
        if _mem.txtone != 0xFFFF and (_mem.txtone & 0x8000) == 0x8000:
933
            tcode, tpol = _get_dcs(_mem.txtone)
934
            mem.dtcs = tcode
935
            txmode = "DTCS"
936
        elif _mem.txtone != 0xFFFF and _mem.txtone != 0x0:
937
            mem.rtone = (_mem.txtone & 0x7fff) / 10.0
938
            txmode = "Tone"
939
        else:
940
            txmode = ""
941
# MRT - Modified the function below to bitwise AND with 0x4000
942
# to check for 1000G Plus DCS Tone decoding
943
        rpol = False
944
        if _mem.rxtone != 0xFFFF and (_mem.rxtone & 0x8000) == 0x8000:
945
            rcode, rpol = _get_dcs(_mem.rxtone)
946
            mem.rx_dtcs = rcode
947
            rxmode = "DTCS"
948
        elif _mem.rxtone != 0xFFFF and _mem.rxtone != 0x0:
949
            mem.ctone = (_mem.rxtone & 0x7fff) / 10.0
950
            rxmode = "Tone"
951
        else:
952
            rxmode = ""
953

    
954
        if txmode == "Tone" and not rxmode:
955
            mem.tmode = "Tone"
956
        elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone:
957
            mem.tmode = "TSQL"
958
        elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs:
959
            mem.tmode = "DTCS"
960
        elif rxmode or txmode:
961
            mem.tmode = "Cross"
962
            mem.cross_mode = "%s->%s" % (txmode, rxmode)
963

    
964
        # always set it even if no dtcs is used
965
        mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N")
966

    
967
        LOG.debug("Got TX %s (%i) RX %s (%i)" %
968
                  (txmode, _mem.txtone, rxmode, _mem.rxtone))
969

    
970
    def get_memory(self, number):
971
        _mem = self._memobj.memory[number]
972
        _nam = self._memobj.names[number]
973

    
974
        mem = chirp_common.Memory()
975
        mem.number = number
976
        _valid = self._memobj.valid[mem.number]
977

    
978
        LOG.debug("Mem %d valid is %s", number, _valid == MEM_VALID)
979
        LOG.debug("Rx Freq %s", _mem.rxfreq)
980
        if (_valid != MEM_VALID) & ((_mem.rxfreq == 0xFFFFFFFF)
981
                                or _mem.rxfreq ==0x00000000):
982
            mem.empty = True
983
            _valid = 0xFF
984
            return mem
985
        elif (_valid != MEM_VALID) & ((_mem.rxfreq != 0xFFFFFFFF)
986
              and (_mem.rxfreq != 0x00000000)):
987
            LOG.debug("Changed chan %d %s", number, "to valid")
988
            _valid = MEM_VALID
989
            mem.empty = False
990
        else:
991
            _valid = MEM_VALID
992
            mem.empty = False
993
        mem.freq = int(_mem.rxfreq) * 10
994
        _rxfreq = _freq_decode(_mem.rxfreq)
995
        _txfreq = _freq_decode(_mem.txfreq)
996
        mem.freq = _rxfreq
997
        LOG.debug("Tx Freq is "+ str(_mem.txfreq))
998
        if  _mem.txfreq == 0xFFFFFFFF:
999
            # TX freq not set
1000
            mem.duplex = "off"
1001
            mem.offset = 0
1002
        elif int(_rxfreq) == int(_txfreq):
1003
            mem.duplex = ""
1004
            mem.offset = 0
1005
        elif abs(_rxfreq - _txfreq) > 70000000:
1006
            mem.duplex = "split"
1007
            mem.offset = _txfreq
1008
        else:
1009
            mem.duplex = _rxfreq > _txfreq and "-" or "+"
1010
            mem.offset = abs(_rxfreq - _txfreq)
1011

    
1012
        if _mem.named:
1013
            mem.name = _str_decode(self._memobj.names[number].name)
1014
        else:
1015
            mem.name = ''
1016

    
1017

    
1018
        self._get_tone(_mem, mem)
1019

    
1020
        mem.skip = "" if bool(_mem.scan_add) else "S"
1021

    
1022
        LOG.debug("Mem Power " + str(_mem.power))
1023
        pwr_index= _mem.power
1024
        if _mem.power == 3:
1025
            pwr_index = 2
1026
            LOG.debug("Force Mem Power to" + str(pwr_index))
1027
        if _mem.power:
1028
            mem.power = self.POWER_LEVELS[pwr_index]
1029
        else: 
1030
            mem.power = self.POWER_LEVELS[0]
1031
        
1032
        # mem.am_mode = _mem.power & 0x2
1033

    
1034
        # LOG.debug("Mem Power Index " + str(_mem.power))
1035
#        mem.power = self.POWER_LEVELS[_mem.power]
1036

    
1037
        if _mem.am_mode:
1038
            if _mem.isnarrow:
1039
                mem.mode = "NAM"
1040
            else:
1041
                mem.mode = "AM"
1042
        else:
1043
            mem.mode = _mem.isnarrow and "NFM" or "FM"
1044

    
1045
        mem.extra = RadioSettingGroup("Extra", "extra")
1046

    
1047
        _scram = _mem.scrambler
1048
        if _mem.scrambler > 8:
1049
            _scram = 0
1050
        # rs = RadioSetting("scrambler", "Scrambler",
1051
        #                   RadioSettingValueList(SCRAMBLER_LIST,
1052
        #                                         SCRAMBLER_LIST[_scram]))
1053
        # mem.extra.append(rs)
1054

    
1055
        # rs = RadioSetting("compander", "Compander",
1056
        #                   RadioSettingValueBoolean(_mem.compander))
1057
        # mem.extra.append(rs)
1058

    
1059
        # rs = RadioSetting("mute_mode", "Mute",
1060
        #                   RadioSettingValueMap(MUTE_MODE_MAP, _mem.mute_mode))
1061
        # mem.extra.append(rs)
1062

    
1063
        return mem
1064

    
1065
    def _set_tone(self, mem, _mem):
1066
        def _set_dcs(code, pol):
1067
            # MRT Change to 0x8000 to
1068
            # set the bit for DCS- code is a decimal version of the code # - NOT OCTAL
1069
            val = int("%i" % code, 10) | 0x8000
1070
            if pol == "R":
1071
                # MRT Change to 0x4000 to set the bit for
1072
                # i/R polarity
1073
                val += 0x4000
1074
            return val
1075

    
1076
        rx_mode = tx_mode = None
1077
        rxtone = txtone = 0x0000
1078

    
1079
        if mem.tmode == "Tone":
1080
            tx_mode = "Tone"
1081
            rx_mode = None
1082
            txtone = int(mem.rtone * 10) 
1083
        elif mem.tmode == "TSQL":
1084
            rx_mode = tx_mode = "Tone"
1085
            rxtone = txtone = int(mem.ctone * 10) 
1086
        elif mem.tmode == "DTCS":
1087
            tx_mode = rx_mode = "DTCS"
1088
            txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0])
1089
            rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1])
1090
        elif mem.tmode == "Cross":
1091
            tx_mode, rx_mode = mem.cross_mode.split("->")
1092
            if tx_mode == "DTCS":
1093
                txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0])
1094
            elif tx_mode == "Tone":
1095
                txtone = int(mem.rtone * 10) 
1096
            if rx_mode == "DTCS":
1097
                rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1])
1098
            elif rx_mode == "Tone":
1099
                rxtone = int(mem.ctone * 10) 
1100

    
1101
        _mem.rxtone = rxtone
1102
        _mem.txtone = txtone
1103

    
1104
        LOG.debug("Set TX %s (%i) RX %s (%i)" %
1105
                  (tx_mode, _mem.txtone, rx_mode, _mem.rxtone))
1106

    
1107
    def set_memory(self, mem):
1108
#   _mem = Stored Memory value 
1109
#    mem = New value from user entry
1110
        number = mem.number
1111
        _mem = self._memobj.memory[number]
1112
        _nam = self._memobj.names[number]
1113
        _valid = self._memobj.valid[mem.number]
1114

    
1115
        # if mem.empty:
1116
        #     _mem.set_raw("\x00" * (_mem.size() / 8))
1117
        #     self._memobj.valid[number] = 0
1118
        #     self._memobj.names[number].set_raw("\x00" * (_nam.size() / 8))
1119
        #     return
1120

    
1121
        if mem.empty:
1122
            LOG.debug("Mem %s is Empty", number)
1123
            self._memobj.valid[number] = 0xFF
1124
            LOG.debug("Set Mem %s Not Valid", number)
1125
            _mem.rxfreq = 0xFFFFFFFF
1126
            LOG.debug("Set Rx Freq = FFFFFFF")
1127
            _mem.txfreq = 0xFFFFFFFF
1128
            LOG.debug("Set Tx Freq = FFFFFFF")
1129
            self._memobj.names[number].set_raw("\xFF" * (_nam.size() / 8))
1130
            LOG.debug("Name %s Cleared", number)
1131
            # The following line is a hack to make CPS happy and not 
1132
            # show memory entries that were deleted with CHIRP
1133
            # _mem=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
1134
            # LOG.debug("Set _mem = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
1135
        else:
1136
            LOG.debug("Mem %s is NOT Empty", number)
1137
            if len(mem.name) > 0:
1138
                LOG.debug("new name = %s", (mem.name))
1139
                _mem.named = True
1140
                name_encoded = _str_encode(mem.name)
1141
                LOG.debug("name endcoded = %s", (name_encoded))
1142
                LOG.debug("number = %s", (number))
1143
                for i in range(0, 8):
1144
                    _nam.name[i] = ord(name_encoded[i])
1145
            else:
1146
                _mem.named = False
1147

    
1148

    
1149
            _mem.rxfreq = _freq_encode(mem.freq)
1150
            if mem.duplex == "off":
1151
                _mem.txfreq = 0xFFFFFFFF
1152
            elif mem.duplex == "split":
1153
                _mem.txfreq = _freq_encode(mem.offset)
1154
            elif mem.duplex == "+":
1155
                _mem.txfreq = _freq_encode(mem.freq + mem.offset)
1156
            elif mem.duplex == "-":
1157
                _mem.txfreq = _freq_encode(mem.freq - mem.offset)
1158
            else:
1159
                _mem.txfreq = _freq_encode(mem.freq)
1160

    
1161
            _mem.scan_add = int(mem.skip != "S")
1162

    
1163
            if mem.mode == "AM":
1164
                _mem.am_mode = True
1165
                _mem.isnarrow = False
1166
            elif mem.mode == "NAM":
1167
                _mem.am_mode = True
1168
                _mem.isnarrow = True
1169
            else:
1170
                _mem.am_mode = False
1171
                if mem.mode =="NFM":
1172
                    _mem.isnarrow = True
1173
                else:
1174
                    _mem.isnarrow = False
1175

    
1176
            # set the tone
1177
            self._set_tone(mem, _mem)
1178
            # MRT set the scrambler and compander to off by default
1179
            # MRT This changes them in the channel memory
1180
            _mem.scrambler = 0
1181
            _mem.compander = 0
1182
            # set the power
1183
            if mem.power:
1184
                _mem.power = self.POWER_LEVELS.index(mem.power)
1185
            else:
1186
                _mem.power = True
1187
            LOG.debug("Set mem.power = %s" % mem.power)
1188
            # pwr_index= mem.power
1189
            # LOG.debug("pwr index = " + str(pwr_index))
1190
            if str(mem.power) == "None":mem.power = 1
1191
            index = self.POWER_LEVELS.index(mem.power)
1192
            LOG.debug("index = %i", (index))
1193
            if index == 2:
1194
                _mem.power = 0b11 #self.POWER_LEVELS.index(mem.power)
1195
            else:
1196
                _mem.power = self.POWER_LEVELS.index(mem.power)
1197
            # Not sure what this bit does yet but it causes the radio to display
1198
            # MED power when the CPS shows Low Power. Forcing it to 0 to keep them 
1199
            # consistent
1200
            _mem.extra_power_bit = 0
1201
            # Set other unknowns to 0 to match default CPS values
1202
            _mem.unknown1 = 0
1203
            _mem.unknown2 = 0
1204
            _mem.unknownbit2 = 0
1205
            _mem.unknown3 = 0
1206
            _mem.Unknown4_shft_dir = 0
1207
            _mem.unknown5 = 0
1208
            
1209
            # if mem.power:
1210
            #     _mem.power = self.POWER_LEVELS.index[mem.power]
1211
            # else:
1212
            #     _mem.power = True
1213

    
1214
            # MRT set to mute mode to QT (not QT+DTMF or QT*DTMF) by default
1215
            # MRT This changes them in the channel memory
1216
            _mem.mute_mode = 1
1217

    
1218
    def _get_settings(self):
1219
        _settings = self._memobj.settings
1220
        _limits = self._memobj.bandlimits
1221
        _oem = self._memobj.oem
1222
#        _vfoa = self._memobj.vfoa
1223
#        _vfob = self._memobj.vfob
1224
#        _scan = self._memobj.scan_groups
1225
#        _call = self._memobj.call_groups
1226
#        _callname = self._memobj.call_names
1227
#        _fmpreset = self._memobj.fm_preset
1228

    
1229
        cfg_grp = RadioSettingGroup("cfg_grp", "Config Settings")
1230
        cfg1_grp = RadioSettingGroup("cfg1_grp", "Config Settings 1")
1231
        cfg2_grp = RadioSettingGroup("cfg2_grp", "Config Settings 2")
1232
        vfoa_grp = RadioSettingGroup("vfoa_grp", "VFO A Settings")
1233
        vfo150_grp = RadioSettingGroup("vfo150_grp", "150M Settings")
1234
        vfo450_grp = RadioSettingGroup("vfo450_grp", "450M Settings")
1235
        # vfo20_grp = RadioSettingGroup("vfo20_grp", "20M Settings")
1236
        vfo50_grp = RadioSettingGroup("vfo50_grp", "50M Settings")
1237
        vfo350_grp = RadioSettingGroup("vfo350_grp", "350M Settings")
1238
        vfo850_grp = RadioSettingGroup("vfo850_grp", "850M Settings")
1239
        vfoabands_grp = RadioSettingGroup("vfoabands_grp", "VFO A Band Settings")
1240
        vfob_grp = RadioSettingGroup("vfob_grp", "VFO B Settings")
1241
        key_grp = RadioSettingGroup("key_grp", "Key Settings")
1242
        fmradio_grp = RadioSettingGroup("fmradio_grp", "FM Broadcast Memory")
1243
        lmt_grp = RadioSettingGroup("lmt_grp", "Frequency Limits")
1244
        lmwrn_grp = RadioSettingGroup("lmwrn_grp", "USE AT YOUR OWN RISK")
1245
        rxlim_grp = RadioSettingGroup("rxlim_grp", "Rx Limits")
1246
        txwrn_grp = RadioSettingGroup("txwrn_grp", "Radio Locked to Tx on GMRS ONLY")
1247
#        txlim_grp = RadioSettingGroup("txlim_grp", "Tx Limits - Not Used by Radio")
1248
        uhf_lmt_grp = RadioSettingGroup("uhf_lmt_grp", "UHF")
1249
        vhf_lmt_grp = RadioSettingGroup("vhf_lmt_grp", "VHF")
1250
        oem_grp = RadioSettingGroup("oem_grp", "Area Message")
1251
        scan_grp = RadioSettingGroup("scan_grp", "Scan Group")
1252
        scanname_grp = RadioSettingGroup("scanname_grp", "Scan Names")
1253
        call_grp = RadioSettingGroup("call_grp", "Call Settings")
1254
        remote_grp = RadioSettingGroup("remote_grp", "Remote Settings")
1255
        extra_grp = RadioSettingGroup("extra_grp",
1256
                                      "Extra Settings"
1257
                                      "\nNOT Changed by RESET or CPS")
1258
        vfo_grp = RadioSettingGroup("vfo_grp",
1259
                                    "Freq Mode Settings")
1260
        memxtras_grp = RadioSettingGroup("memxtras_grp", "Memory Extras")
1261
        cfg_grp.append(cfg1_grp)
1262
        cfg_grp.append(cfg2_grp)
1263
        cfg_grp.append(oem_grp)
1264
        lmt_grp.append(lmwrn_grp)
1265
        lmt_grp.append(txwrn_grp)        
1266
        lmt_grp.append(rxlim_grp)
1267
        # lmt_grp.append(txlim_grp)
1268
        # extra_grp.append(lmt_grp)
1269
        vfo_grp.append(vfoa_grp)
1270
        vfo_grp.append(vfob_grp)
1271
        vfoa_grp.append(vfo150_grp)
1272
        vfoa_grp.append(vfo450_grp) 
1273
        # vfoa_grp.append(vfo20_grp) 
1274
        vfoa_grp.append(vfo50_grp)
1275
        vfoa_grp.append(vfo350_grp) 
1276
        vfoa_grp.append(vfo850_grp)
1277
        scan_grp.append(scanname_grp)
1278
        
1279
        group = RadioSettings(cfg_grp, vfo_grp, fmradio_grp, 
1280
                        remote_grp, scan_grp, lmt_grp)
1281

    
1282
# Memory extras
1283
        # rs = RadioSetting("_mem.mute_mode", "Mute Mode"+str(number),
1284
        #                   RadioSettingValueBoolean(_mem.mute_mode))
1285
        # memxtras_grp.append(rs)
1286

    
1287
# Configuration Settings
1288

    
1289
        rs = RadioSetting("roger", "Roger Beep",
1290
                          RadioSettingValueList(ROGER_LIST,
1291
                                                ROGER_LIST[_settings.
1292
                                                           roger]))
1293
        cfg1_grp.append(rs)
1294

    
1295
        rs = RadioSetting("beep", "Keypad Beep",
1296
                          RadioSettingValueBoolean(_settings.beep))
1297
        cfg1_grp.append(rs)
1298

    
1299
        rs = RadioSetting("voice", "Voice Guide",
1300
                          RadioSettingValueBoolean(_settings.voice))
1301
        cfg1_grp.append(rs)
1302

    
1303
        rs = RadioSetting("bcl_a", "Busy Channel Lock-out A",
1304
                          RadioSettingValueBoolean(_settings.bcl_a))
1305
        cfg1_grp.append(rs)
1306

    
1307
        rs = RadioSetting("bcl_b", "Busy Channel Lock-out B",
1308
                          RadioSettingValueBoolean(_settings.bcl_b))
1309
        cfg1_grp.append(rs)
1310

    
1311
        rs = RadioSetting("sc_rev", "Scan Mode",
1312
                          RadioSettingValueMap(SC_REV_MAP, _settings.sc_rev))
1313
        cfg1_grp.append(rs)
1314
        rs = RadioSetting("tot", "Timeout Timer (TOT)",
1315
                          RadioSettingValueMap(
1316
                              TOT_MAP, _settings.tot))
1317
        cfg1_grp.append(rs)
1318

    
1319
        rs = RadioSetting("toa", "Overtime Alarm (TOA)",
1320
                          RadioSettingValueList(
1321
                              TOA_LIST, TOA_LIST[_settings.toa]))
1322
        cfg1_grp.append(rs)
1323

    
1324
        # rs = RadioSetting("ani_sw", "Caller ID Tx - ANI-SW",
1325
        #                   RadioSettingValueBoolean(_settings.ani_sw))
1326
        # cfg1_grp.append(rs)
1327

    
1328
        rs = RadioSetting("ring", "Ring Time (Sec)",
1329
                          RadioSettingValueList(RING_LIST,
1330
                           RING_LIST[_settings.ring]))
1331
        cfg1_grp.append(rs)
1332

    
1333

    
1334
        rs = RadioSetting("dtmfsf", "Sidetone",
1335
                          RadioSettingValueList(
1336
                              DTMF_ST_LIST,
1337
                              DTMF_ST_LIST[_settings.dtmfsf]))
1338
        cfg1_grp.append(rs)
1339

    
1340

    
1341
        rs = RadioSetting("ptt_id", "DTMF ID",
1342
                          RadioSettingValueMap(PTT_ID_MAP, _settings.ptt_id))
1343
        cfg1_grp.append(rs)
1344

    
1345

    
1346
        rs = RadioSetting("wt_led", "Standby LED",
1347
                          RadioSettingValueList(
1348
                              BACKLIGHT_LIST,
1349
                              BACKLIGHT_LIST[_settings.wt_led]))
1350
        cfg1_grp.append(rs)
1351

    
1352
        rs = RadioSetting("tx_led", "TX LED",
1353
                          RadioSettingValueList(
1354
                              BACKLIGHT_LIST,
1355
                              BACKLIGHT_LIST[_settings.tx_led]))
1356
        cfg1_grp.append(rs)
1357

    
1358
        rs = RadioSetting("rx_led", "Rx LED",
1359
                          RadioSettingValueList(
1360
                              BACKLIGHT_LIST,
1361
                              BACKLIGHT_LIST[_settings.rx_led]))
1362
        cfg1_grp.append(rs)
1363

    
1364
        rs = RadioSetting("prich_sw", "Priority Scan",
1365
                          RadioSettingValueList(
1366
                            PRI_CH_SCAN_LIST,
1367
                            PRI_CH_SCAN_LIST[_settings.prich_sw]))
1368
        cfg1_grp.append(rs)
1369

    
1370
        rs = RadioSetting("spk_cont", "Speaker Control",
1371
                          RadioSettingValueMap(
1372
                              SPEAKER_MAP,
1373
                              _settings.spk_cont))
1374
        cfg1_grp.append(rs)
1375

    
1376
        rs = RadioSetting("autolock", "Autolock",
1377
                          RadioSettingValueBoolean(_settings.autolock))
1378
        cfg1_grp.append(rs)
1379

    
1380
        rs = RadioSetting("low_v", "Voltage Alert",
1381
                          RadioSettingValueBoolean(_settings.low_v))
1382
        cfg1_grp.append(rs)
1383

    
1384
        rs = RadioSetting("fan", "Fan Setting",
1385
                          RadioSettingValueList(
1386
                              FAN_MODE_LIST,
1387
                              FAN_MODE_LIST[_settings.fan]))
1388
        cfg1_grp.append(rs)
1389

    
1390
        rs = RadioSetting("apo_time", "Auto Power-Off (Min)",
1391
                          RadioSettingValueList(
1392
                              APO_TIME_LIST,
1393
                              APO_TIME_LIST[_settings.apo_time]))
1394
        cfg1_grp.append(rs)
1395

    
1396
        rs = RadioSetting("alert", "Alert Tone(Hz)",
1397
                          RadioSettingValueMap(ALERT_MAP, _settings.alert))
1398
        cfg1_grp.append(rs)
1399
        rs = RadioSetting("m_pwr", "Medium Power Level (W)",
1400
                          RadioSettingValueMap(M_POWER_MAP,
1401
                                               _settings.m_pwr))
1402
        cfg1_grp.append(rs)
1403

    
1404
        rs = RadioSetting("rpt_set_model", "Repeater Mode",
1405
                          RadioSettingValueMap(
1406
                              RPT_MODE_MAP,
1407
                              _settings.rpt_set_model))
1408
        cfg2_grp.append(rs)
1409

    
1410
        rs = RadioSetting("rpt_spk", "Repeater Speaker Switch (RPT-SPK)",
1411
                          RadioSettingValueBoolean(_settings.rpt_spk))
1412
        cfg2_grp.append(rs)
1413

    
1414
        rs = RadioSetting("rpt_ptt", "Repeater PTT (RPT-PTT)",
1415
                          RadioSettingValueBoolean(_settings.rpt_ptt))
1416
        cfg2_grp.append(rs)
1417

    
1418
        rs = RadioSetting("dtmf_time", "DTMF Tx Duration (ms)",
1419
                          RadioSettingValueList(
1420
                              DTMF_TIMES,
1421
                              DTMF_TIMES[_settings.dtmf_time]))
1422
        cfg2_grp.append(rs)
1423
        rs = RadioSetting("dtmf_int", "DTMF Interval (ms)",
1424
                          RadioSettingValueList(
1425
                              DTMF_INTERVALS,
1426
                              DTMF_INTERVALS[_settings.dtmf_int]))
1427
        cfg2_grp.append(rs)
1428

    
1429
        rs = RadioSetting("sc_qt", "Tone Save",
1430
                          RadioSettingValueMap(
1431
                              SC_QT_MAP,_settings.sc_qt))
1432
        cfg2_grp.append(rs)
1433

    
1434
        rs = RadioSetting("pri_ch", "Priority Channel",
1435
                          RadioSettingValueInteger(
1436
                              1, 999, _chnum_decode(_settings.pri_ch)))
1437
        cfg2_grp.append(rs)
1438

    
1439
        rs = RadioSetting("ptt_id_dly", "DTMF ID Delay (ms)",
1440
                          RadioSettingValueMap(PTT_ID_DELAY_MAP,
1441
                                               _settings.ptt_id_dly))
1442
        cfg2_grp.append(rs)
1443

    
1444
        rs = RadioSetting("rc_sw", "Remote Control RC-SW",
1445
                          RadioSettingValueBoolean(_settings.rc_sw))
1446
        cfg2_grp.append(rs)
1447

    
1448
        rs = RadioSetting("scan_det", "Tone Scan",
1449
                          RadioSettingValueBoolean(_settings.scan_det))
1450
        cfg2_grp.append(rs)
1451

    
1452
        rs = RadioSetting("menu", "Menu Available",
1453
                          RadioSettingValueBoolean(_settings.menu))
1454
        cfg2_grp.append(rs)
1455

    
1456
        rs = RadioSetting("thr_vol_tx", "Tx Voltage Limit",
1457
                          RadioSettingValueBoolean(_settings.thr_vol_tx))
1458
        cfg2_grp.append(rs)
1459

    
1460
        rs = RadioSetting("hold_time_rpt", "Repeater Hold Time (ms)",
1461
                          RadioSettingValueList(
1462
                              HOLD_TIMES,
1463
                              HOLD_TIMES[_settings.hold_time_rpt]))
1464
        cfg2_grp.append(rs)
1465

    
1466
        rs = RadioSetting("auto_am", "Auto AM",
1467
                          RadioSettingValueBoolean(_settings.auto_am))
1468
        cfg2_grp.append(rs)
1469

    
1470
        rs = RadioSetting("rpt_tone", "Repeat Tone",
1471
                          RadioSettingValueBoolean(_settings.rpt_tone))
1472
        cfg2_grp.append(rs)
1473

    
1474
        rs = RadioSetting("pf1_set", "PF1 setting",
1475
                          RadioSettingValueList(
1476
                              PF1_SETTINGS,
1477
                              PF1_SETTINGS[_settings.pf1_set]))
1478
        cfg2_grp.append(rs)
1479

    
1480
        rs = RadioSetting("settings.thr_vol_lvl", "Tx Voltage Min",
1481
                          RadioSettingValueFloat(
1482
                              9.5, 10.5, _settings.thr_vol_lvl / 100.0 , 0.1, 1))
1483
        cfg2_grp.append(rs)
1484

    
1485
        dtmfchars = "0123456789"
1486
        _code =''
1487
        test = int(_oem.mode_psw)
1488
        _codeobj = '0x{0:0{1}X}'.format(test,6)
1489
        LOG.debug("codeobj = %s" % _codeobj)
1490
        _psw = str(_codeobj)
1491
        for i in range(2,8):
1492
            LOG.debug("psw[i] = %s" % _psw[i])
1493
            if _psw[i] in dtmfchars:
1494
                _code += _psw[i]
1495
        val_psw = int(_code)
1496
        LOG.debug("psw = %s" % val_psw)
1497
        val_psw = RadioSettingValueString(6, 6, _code, False)
1498
        val_psw.set_charset(dtmfchars)
1499
        rs = RadioSetting("oem.mode_psw", "Freq Mode Password", val_psw)
1500
        def apply_psw_id(setting, obj):
1501
            val2 = hex(int(str(val_psw),16))
1502
            LOG.debug("val2= %s" % val2)
1503
            if (int(val2,16) != 0):
1504
               while len(val2) < 8:
1505
                   val2 += '0'
1506
            psw = int(str(val2),16)
1507
            LOG.debug("val3= %s" % psw)
1508
            LOG.debug("val= %s" % val_psw)
1509
            obj.mode_psw = psw
1510
        rs.set_apply_callback(apply_psw_id, _oem)
1511
        cfg2_grp.append(rs)
1512

    
1513
        rs = RadioSetting("ABR", "Backlight On Time",
1514
                          RadioSettingValueList(
1515
                              ABR_LIST,
1516
                              ABR_LIST[_settings.ABR]))
1517
        cfg2_grp.append(rs)
1518

    
1519
        rs = RadioSetting("KeyA", "Key A",
1520
                          RadioSettingValueList(
1521
                              KEY_LIST,
1522
                              KEY_LIST[_settings.KeyA]))
1523
        cfg2_grp.append(rs)
1524
        rs = RadioSetting("KeyB", "Key B",
1525
                          RadioSettingValueList(
1526
                              KEY_LIST,
1527
                              KEY_LIST[_settings.KeyB]))
1528
        cfg2_grp.append(rs)
1529
        rs = RadioSetting("KeyC", "Key C",
1530
                          RadioSettingValueList(
1531
                              KEY_LIST,
1532
                              KEY_LIST[_settings.KeyC]))
1533
        cfg2_grp.append(rs)
1534
        rs = RadioSetting("KeyD", "Key D",
1535
                          RadioSettingValueList(
1536
                              KEY_LIST,
1537
                              KEY_LIST[_settings.KeyD]))
1538
        cfg2_grp.append(rs)
1539

    
1540
        rs = RadioSetting("key_lock", "Key Lock",
1541
                          RadioSettingValueBoolean(_settings.key_lock))
1542
        cfg2_grp.append(rs)
1543

    
1544
        rs = RadioSetting("act_area", "Active Area",
1545
                          RadioSettingValueList(
1546
                              ACTIVE_AREA_LIST,
1547
                              ACTIVE_AREA_LIST[_settings.act_area]))
1548
        cfg2_grp.append(rs)
1549
        rs = RadioSetting("tdr_off", "TDR",
1550
                          RadioSettingValueList(
1551
                              TDR_LIST,
1552
                              TDR_LIST[_settings.tdr_off]))
1553
        cfg2_grp.append(rs)
1554

    
1555
# Freq Limits settings
1556
        
1557
        # Convert Integer back to correct limit HEX value:  limit = hex(int(str(limit*10),16))        
1558
        # # LOG.debug("limit =" % limit)
1559

    
1560
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_144M_ChA_rx_start, 10)))
1561
        _temp = int(int(_temp[2:])/10.0)
1562
        val= RadioSettingValueInteger(0,999, _temp)
1563
        rs = RadioSetting("bandlimits.limit_144M_ChA_rx_start", "144M ChA Rx Lower Limit (MHz)",
1564
                          val)
1565
        rxlim_grp.append(rs)
1566

    
1567
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_144M_ChA_rx_stop, 10)))
1568
        _temp = int(int(_temp[2:])/10.0)
1569
        val= RadioSettingValueInteger(0,999, _temp)
1570
        rs = RadioSetting("bandlimits.limit_144M_ChA_rx_stop", "144M ChA Rx Upper Limit (MHz)",
1571
                          RadioSettingValueInteger(0,999,
1572
                              val))
1573
        rxlim_grp.append(rs)
1574

    
1575
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_144M_ChB_rx_start, 10)))
1576
        _temp = int(int(_temp[2:])/10.0)
1577
        val= RadioSettingValueInteger(0,999, _temp)
1578
        rs = RadioSetting("bandlimits.limit_144M_ChB_rx_start", "144M ChB Rx Lower Limit (MHz)",
1579
                          val)
1580
        rxlim_grp.append(rs)
1581

    
1582
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_144M_ChB_rx_stop, 10)))
1583
        _temp = int(int(_temp[2:])/10.0)
1584
        val= RadioSettingValueInteger(0,999, _temp)
1585
        rs = RadioSetting("bandlimits.limit_144M_ChB_rx_stop", "144M ChB Rx Upper Limit (MHz)",
1586
                          RadioSettingValueInteger(0,999,
1587
                              val))
1588
        rxlim_grp.append(rs)
1589

    
1590
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_70cm_rx_start, 10)))
1591
        _temp = int(int(_temp[2:])/10.0)
1592
        val= RadioSettingValueInteger(0,999, _temp)
1593
        rs = RadioSetting("bandlimits.limit_70cm_rx_start", "450M Rx Lower Limit (MHz)",
1594
                          RadioSettingValueInteger(0,999,
1595
                              val))
1596
        rxlim_grp.append(rs)
1597

    
1598
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_70cm_rx_stop, 10)))
1599
        _temp = int(int(_temp[2:])/10.0)
1600
        val= RadioSettingValueInteger(0,999, _temp)
1601
        rs = RadioSetting("bandlimits.limit_70cm_rx_stop", "450M Rx Upper Limit (MHz)",
1602
                          RadioSettingValueInteger(0,999,
1603
                              val))
1604
        rxlim_grp.append(rs)
1605

    
1606
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_10m_rx_start, 10)))
1607
        # _temp = int(int(_temp[2:])/10.0)
1608
        # val= RadioSettingValueInteger(0,999, _temp)
1609
        # rs = RadioSetting("bandlimits.limit_10m_rx_start", "20M Rx Lower Limit (MHz)",
1610
        #                   RadioSettingValueInteger(0,999,
1611
        #                       val))
1612
        # rxlim_grp.append(rs)
1613

    
1614
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_10m_rx_stop, 10)))
1615
        # _temp = int(int(_temp[2:])/10.0)
1616
        # val= RadioSettingValueInteger(0,999, _temp)
1617
        # rs = RadioSetting("bandlimits.limit_10m_rx_stop", "20M Rx Upper Limit (MHz)",
1618
        #                   RadioSettingValueInteger(0,999,
1619
        #                       val))
1620
        # rxlim_grp.append(rs)
1621

    
1622
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_6m_rx_start, 10)))
1623
        _temp = int(int(_temp[2:])/10.0)
1624
        val= RadioSettingValueInteger(0,999, _temp)
1625
        rs = RadioSetting("bandlimits.limit_6m_rx_start", "50M Rx Lower Limit (MHz)",
1626
                          RadioSettingValueInteger(0,999,
1627
                              val))
1628
        rxlim_grp.append(rs)
1629

    
1630
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_6m_rx_stop, 10)))
1631
        _temp = int(int(_temp[2:])/10.0)
1632
        val= RadioSettingValueInteger(0,999, _temp)
1633
        rs = RadioSetting("bandlimits.limit_6m_rx_stop", "50M Rx Upper Limit (MHz)",
1634
                          RadioSettingValueInteger(0,999,
1635
                              val))
1636
        rxlim_grp.append(rs)
1637

    
1638
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_350M_rx_start, 10)))
1639
        _temp = int(int(_temp[2:])/10.0)
1640
        val= RadioSettingValueInteger(0,999, _temp)
1641
        rs = RadioSetting("bandlimits.limit_350M_rx_start", "350M Rx Lower Limit (MHz)",
1642
                          RadioSettingValueInteger(0,999,
1643
                              val))
1644
        rxlim_grp.append(rs)
1645

    
1646
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_350M_rx_stop, 10)))
1647
        _temp = int(int(_temp[2:])/10.0)
1648
        val= RadioSettingValueInteger(0,999, _temp)
1649
        rs = RadioSetting("bandlimits.limit_350M_rx_stop", "350M Rx Upper Limit (MHz)",
1650
                          RadioSettingValueInteger(0,999,
1651
                              val))
1652
        rxlim_grp.append(rs)
1653

    
1654
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_850M_rx_start, 10)))
1655
        _temp = int(int(_temp[2:])/10.0)
1656
        val= RadioSettingValueInteger(0,999, _temp)
1657
        rs = RadioSetting("bandlimits.limit_850M_rx_start", "850M Rx Lower Limit (MHz)",
1658
                          RadioSettingValueInteger(0,999,
1659
                              val))
1660
        rxlim_grp.append(rs)
1661

    
1662
        _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_850M_rx_stop, 10)))
1663
        _temp = int(int(_temp[2:])/10.0)
1664
        val= RadioSettingValueInteger(0,999, _temp)
1665
        rs = RadioSetting("bandlimits.limit_850M_rx_stop", "850M Rx Upper Limit (MHz)",
1666
                          RadioSettingValueInteger(0,999,
1667
                              val))
1668
        rxlim_grp.append(rs)
1669

    
1670

    
1671
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_144M_ChA_tx_start, 10)))
1672
        # _temp = int(int(_temp[2:])/10.0)
1673
        # val= RadioSettingValueInteger(0,999, _temp)
1674
        # rs = RadioSetting("bandlimits.limit_144M_ChA_tx_start", "144M ChA Tx Lower Limit (MHz)",
1675
        #                   RadioSettingValueInteger(0,999,
1676
        #                       val))
1677
        # txlim_grp.append(rs)
1678

    
1679
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_144M_ChA_tx_stop, 10)))
1680
        # _temp = int(int(_temp[2:])/10.0)
1681
        # val= RadioSettingValueInteger(0,999, _temp)
1682
        # rs = RadioSetting("bandlimits.limit_144M_ChA_tx_stop", "144M ChA Tx Upper Limit (MHz)",
1683
        #                   RadioSettingValueInteger(0,999,
1684
        #                       val))
1685
        # txlim_grp.append(rs)
1686

    
1687
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_70cm_tx_start, 10)))
1688
        # _temp = int(int(_temp[2:])/10.0)
1689
        # val= RadioSettingValueInteger(0,999, _temp)
1690
        # rs = RadioSetting("bandlimits.limit_70cm_tx_start", "450M Tx Lower Limit (MHz)",
1691
        #                   RadioSettingValueInteger(0,999,
1692
        #                       val))
1693
        # txlim_grp.append(rs)
1694

    
1695
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_70cm_tx_stop, 10)))
1696
        # _temp = int(int(_temp[2:])/10.0)
1697
        # val= RadioSettingValueInteger(0,999, _temp)
1698
        # rs = RadioSetting("bandlimits.limit_70cm_tx_stop", "450M tx Upper Limit (MHz)",
1699
        #                   RadioSettingValueInteger(0,999,
1700
        #                       val))
1701
        # txlim_grp.append(rs)
1702

    
1703
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_10m_tx_start, 10)))
1704
        # _temp = int(int(_temp[2:])/10.0)
1705
        # val= RadioSettingValueInteger(0,999, _temp)
1706
        # rs = RadioSetting("bandlimits.limit_10m_tx_start", "20M tx Lower Limit (MHz)",
1707
        #                   RadioSettingValueInteger(0,999,
1708
        #                       val))
1709
        # txlim_grp.append(rs)
1710

    
1711
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_10m_tx_stop, 10)))
1712
        # _temp = int(int(_temp[2:])/10.0)
1713
        # val= RadioSettingValueInteger(0,999, _temp)
1714
        # rs = RadioSetting("bandlimits.limit_10m_tx_stop", "20M tx Upper Limit (MHz)",
1715
        #                   RadioSettingValueInteger(0,999,
1716
        #                       val))
1717
        # txlim_grp.append(rs)
1718

    
1719
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_6m_tx_start, 10)))
1720
        # _temp = int(int(_temp[2:])/10.0)
1721
        # val= RadioSettingValueInteger(0,999, _temp)
1722
        # rs = RadioSetting("bandlimits.limit_6m_tx_start", "50M tx Lower Limit (MHz)",
1723
        #                   RadioSettingValueInteger(0,999,
1724
        #                       val))
1725
        # txlim_grp.append(rs)
1726

    
1727
        # _temp =str(hex(int("%i" % self._memobj.bandlimits.limit_6m_tx_stop, 10)))
1728
        # _temp = int(int(_temp[2:])/10.0)
1729
        # val= RadioSettingValueInteger(0,999, _temp)
1730
        # rs = RadioSetting("bandlimits.limit_6m_tx_stop", "50M tx Upper Limit (MHz)",
1731
        #                   RadioSettingValueInteger(0,999,
1732
        #                       val))
1733
        # txlim_grp.append(rs)
1734

    
1735
# VFO Settings
1736
        rs = RadioSetting("vfomode_a", "VFO A Working Mode",
1737
                          RadioSettingValueMap(WORKMODE_MAP,
1738
                                               _settings.vfomode_a))
1739
        vfoa_grp.append(rs)
1740

    
1741
        rs = RadioSetting("vfoband_a", "VFO A Current Band",
1742
                          RadioSettingValueMap(VFOBAND_MAP,
1743
                                               _settings.vfoband_a))
1744
        vfoa_grp.append(rs)
1745

    
1746
        rs = RadioSetting("vfochan_a", "VFO A Channel",
1747
                          RadioSettingValueInteger(1, 999,
1748
                              _chnum_decode(_settings.vfochan_a)))
1749
        vfoa_grp.append(rs)
1750

    
1751
        rs = RadioSetting("vfosquelch_a", "VFO A Squelch",
1752
                          RadioSettingValueInteger(0, 9,
1753
                              _settings.vfosquelch_a))
1754
        vfoa_grp.append(rs)
1755
        rs = RadioSetting("vfostep_a", "VFO A Step",
1756
                          RadioSettingValueList(
1757
                            STEP_LIST,
1758
                            STEP_LIST[_settings.vfostep_a]))
1759
        vfoa_grp.append(rs)
1760
######################
1761

    
1762
        rs = RadioSetting("vfofreq1", "VFO 150M Freq",
1763
                          RadioSettingValueFloat(
1764
                             0, 999.999999, (_freq_decode
1765
                             (_settings.vfofreq1)/1000000.0) ,0.000001, 6))
1766
        vfo150_grp.append(rs)
1767

    
1768
        # rs = RadioSetting("vfoofst1", "VFO 150M Offset",
1769
        #                   RadioSettingValueFloat(
1770
        #                       0, 999.999999, (_freq_decode
1771
        #                       (_settings.vfoofst1)/1000000.0),0.000001, 6))
1772
        # vfo150_grp.append(rs)
1773

    
1774
        rs = RadioSetting("rxtone1", "VFO 150M Rx tone",
1775
                          RadioSettingValueMap(
1776
                            TONE_MAP, _settings.rxtone1))
1777
        vfo150_grp.append(rs)
1778

    
1779
        rs = RadioSetting("txtone1", "VFO 150M Tx tone",
1780
                          RadioSettingValueMap(
1781
                            TONE_MAP, _settings.txtone1))
1782
        vfo150_grp.append(rs)
1783

    
1784
        rs = RadioSetting("power1", "VFO 150M Power",
1785
                          RadioSettingValueMap(
1786
                            POWER_MAP, _settings.power1))
1787
        vfo150_grp.append(rs)
1788

    
1789
        rs = RadioSetting("narrow1", "VFO 150M W/N",
1790
                          RadioSettingValueMap(
1791
                            BANDWIDTH_MAP, _settings.narrow1))
1792
        vfo150_grp.append(rs)
1793

    
1794
        rs = RadioSetting("mute1", "VFO 150M SP Mute",
1795
                          RadioSettingValueMap(
1796
                            MUTE_MODE_MAP, _settings.mute1))
1797
        vfo150_grp.append(rs)
1798

    
1799
        rs = RadioSetting("shft_dir1", "VFO 150M Repeater",
1800
                          RadioSettingValueBoolean(
1801
                            _settings.shft_dir1))
1802
        vfo150_grp.append(rs)
1803

    
1804
        rs = RadioSetting("compander1", "VFO 150M Compander",
1805
                          RadioSettingValueBoolean(
1806
                            _settings.compander1))
1807
        vfo150_grp.append(rs)
1808

    
1809
        rs = RadioSetting("scrambler1", "VFO 150M Descrambler",
1810
                          RadioSettingValueList(
1811
                            SCRAMBLER_LIST,
1812
                            SCRAMBLER_LIST[_settings.scrambler1]))
1813
        vfo150_grp.append(rs)
1814
        rs = RadioSetting("am_mode1", "VFO 150M AM Mode",
1815
                          RadioSettingValueBoolean(
1816
                            _settings.am_mode1))
1817
        vfo150_grp.append(rs)
1818
############################
1819

    
1820
        rs = RadioSetting("vfofreq2", "VFO 450M Freq",
1821
                          RadioSettingValueFloat(
1822
                             0, 999.999999, (_freq_decode
1823
                             (_settings.vfofreq2)/1000000.0) ,0.000001, 6))
1824
        vfo450_grp.append(rs)
1825

    
1826
        # rs = RadioSetting("vfoofst2", "VFO 450M Offset",
1827
        #                   RadioSettingValueFloat(
1828
        #                       0, 999.999999, (_freq_decode
1829
        #                       (_settings.vfoofst2)/1000000.0),0.000001, 6))
1830
        # vfo450_grp.append(rs)
1831

    
1832
        rs = RadioSetting("rxtone2", "VFO 450M Rx tone",
1833
                          RadioSettingValueMap(
1834
                            TONE_MAP, _settings.rxtone2))
1835
        vfo450_grp.append(rs)
1836

    
1837
        rs = RadioSetting("txtone2", "VFO 450M Tx tone",
1838
                          RadioSettingValueMap(
1839
                            TONE_MAP, _settings.txtone2))
1840
        vfo450_grp.append(rs)
1841
        
1842
        rs = RadioSetting("power2", "VFO 450M Power",
1843
                          RadioSettingValueMap(
1844
                            POWER_MAP, _settings.power2))
1845
        vfo450_grp.append(rs)
1846

    
1847
        rs = RadioSetting("narrow2", "VFO 450M W/N",
1848
                          RadioSettingValueMap(
1849
                            BANDWIDTH_MAP, _settings.narrow2))
1850
        vfo450_grp.append(rs)
1851

    
1852
        rs = RadioSetting("mute2", "VFO 450M SP Mute",
1853
                          RadioSettingValueMap(
1854
                            MUTE_MODE_MAP, _settings.mute2))
1855
        vfo450_grp.append(rs)
1856

    
1857
        rs = RadioSetting("shft_dir2", "VFO 450M Repeater",
1858
                          RadioSettingValueBoolean(
1859
                            _settings.shft_dir2))
1860
        vfo450_grp.append(rs)
1861

    
1862
        rs = RadioSetting("compander2", "VFO 450M Compander",
1863
                          RadioSettingValueBoolean(
1864
                            _settings.compander2))
1865
        vfo450_grp.append(rs)
1866

    
1867
        rs = RadioSetting("scrambler2", "VFO 450M Descrambler",
1868
                          RadioSettingValueList(
1869
                            SCRAMBLER_LIST,
1870
                            SCRAMBLER_LIST[_settings.scrambler2]))
1871
        vfo450_grp.append(rs)
1872

    
1873
        rs = RadioSetting("am_mode2", "VFO 450M AM Mode",
1874
                          RadioSettingValueBoolean(
1875
                            _settings.am_mode2))
1876
        vfo450_grp.append(rs)
1877
############################
1878
        # rs = RadioSetting("vfofreq3", "VFO 20M Freq",
1879
        #                   RadioSettingValueFloat(
1880
        #                      0, 999.999999, (_freq_decode
1881
        #                      (_settings.vfofreq3)/1000000.0) ,0.000001, 6))
1882
        # vfo20_grp.append(rs)
1883

    
1884
        # rs = RadioSetting("vfoofst3", "VFO 20M Offset",
1885
        #                   RadioSettingValueFloat(
1886
        #                       0, 999.999999, (_freq_decode
1887
        #                       (_settings.vfoofst3)/1000000.0),0.000001, 6))
1888
        # vfo20_grp.append(rs)
1889

    
1890
        # rs = RadioSetting("rxtone3", "VFO 20M Rx tone",
1891
        #                   RadioSettingValueMap(
1892
        #                     TONE_MAP, _settings.rxtone3))
1893
        # vfo20_grp.append(rs)
1894

    
1895
        # rs = RadioSetting("txtone3", "VFO 20M Tx tone",
1896
        #                   RadioSettingValueMap(
1897
        #                     TONE_MAP, _settings.txtone3))
1898
        # vfo20_grp.append(rs)
1899
        
1900
        # rs = RadioSetting("power3", "VFO 20M Power",
1901
        #                   RadioSettingValueMap(
1902
        #                     POWER_MAP, _settings.power3))
1903
        # vfo20_grp.append(rs)
1904

    
1905
        # rs = RadioSetting("narrow3", "VFO 20M Bandwidth",
1906
        #                   RadioSettingValueMap(
1907
        #                     BANDWIDTH_MAP, _settings.narrow3))
1908
        # vfo20_grp.append(rs)
1909

    
1910
        # rs = RadioSetting("mute3", "VFO 20M Mute Mode",
1911
        #                   RadioSettingValueMap(
1912
        #                     MUTE_MODE_MAP, _settings.mute3))
1913
        # vfo20_grp.append(rs)
1914

    
1915
        # rs = RadioSetting("shft_dir3", "VFO 20M Repeater",
1916
        #                   RadioSettingValueList(
1917
        #                     DUPLEX_LIST,
1918
        #                     DUPLEX_LIST[_settings.shft_dir3]))
1919
        # vfo20_grp.append(rs)
1920

    
1921
        # rs = RadioSetting("compander3", "VFO 20M Compander",
1922
        #                   RadioSettingValueBoolean(
1923
        #                     _settings.compander3))
1924
        # vfo20_grp.append(rs)
1925

    
1926
        # rs = RadioSetting("scrambler3", "VFO 20M Descrambler",
1927
        #                   RadioSettingValueList(
1928
        #                     SCRAMBLER_LIST,
1929
        #                     SCRAMBLER_LIST[_settings.scrambler3]))
1930
        # vfo20_grp.append(rs)
1931

    
1932
        # rs = RadioSetting("am_mode3", "VFO 20M AM Mode",
1933
        #                   RadioSettingValueBoolean(
1934
        #                     _settings.am_mode3))
1935
        # vfo20_grp.append(rs)
1936
############################
1937
        rs = RadioSetting("vfofreq4", "VFO 50M Freq",
1938
                          RadioSettingValueFloat(
1939
                             0, 999.999999, (_freq_decode
1940
                             (_settings.vfofreq4)/1000000.0) ,0.000001, 6))
1941
        vfo50_grp.append(rs)
1942

    
1943
        # rs = RadioSetting("vfoofst4", "VFO 50M Offset",
1944
        #                   RadioSettingValueFloat(
1945
        #                       0, 999.999999, (_freq_decode
1946
        #                       (_settings.vfoofst4)/1000000.0),0.000001, 6))
1947
        # vfo50_grp.append(rs)
1948

    
1949
        rs = RadioSetting("rxtone4", "VFO 50M Rx tone",
1950
                          RadioSettingValueMap(
1951
                            TONE_MAP, _settings.rxtone4))
1952
        vfo50_grp.append(rs)
1953

    
1954
        rs = RadioSetting("txtone4", "VFO 50M Tx tone",
1955
                          RadioSettingValueMap(
1956
                            TONE_MAP, _settings.txtone4))
1957
        vfo50_grp.append(rs)
1958
        
1959
        rs = RadioSetting("power4", "VFO 50M Power",
1960
                          RadioSettingValueMap(
1961
                            POWER_MAP, _settings.power4))
1962
        vfo50_grp.append(rs)
1963

    
1964
        rs = RadioSetting("narrow4", "VFO 50M W/N",
1965
                          RadioSettingValueMap(
1966
                            BANDWIDTH_MAP, _settings.narrow4))
1967
        vfo50_grp.append(rs)
1968

    
1969
        rs = RadioSetting("mute4", "VFO 50M SP Mute",
1970
                          RadioSettingValueMap(
1971
                            MUTE_MODE_MAP, _settings.mute4))
1972
        vfo50_grp.append(rs)
1973

    
1974
        rs = RadioSetting("shft_dir4", "VFO 50M Repeater",
1975
                          RadioSettingValueBoolean(
1976
                            _settings.shft_dir4))
1977
        vfo50_grp.append(rs)
1978

    
1979
        rs = RadioSetting("compander4", "VFO 50M Compander",
1980
                          RadioSettingValueBoolean(
1981
                            _settings.compander4))
1982
        vfo50_grp.append(rs)
1983

    
1984
        rs = RadioSetting("scrambler4", "VFO 50M Descrambler",
1985
                          RadioSettingValueList(
1986
                            SCRAMBLER_LIST,
1987
                            SCRAMBLER_LIST[_settings.scrambler4]))
1988
        vfo50_grp.append(rs)
1989

    
1990
        rs = RadioSetting("am_mode4", "VFO 50M AM Mode",
1991
                          RadioSettingValueBoolean(
1992
                            _settings.am_mode4))
1993
        vfo50_grp.append(rs)
1994
############################
1995
        rs = RadioSetting("vfofreq5", "VFO 350M Freq",
1996
                          RadioSettingValueFloat(
1997
                             0, 999.999999, (_freq_decode
1998
                             (_settings.vfofreq5)/1000000.0) ,0.000001, 6))
1999
        vfo350_grp.append(rs)
2000

    
2001
        # rs = RadioSetting("vfoofst5", "VFO 350M Offset",
2002
        #                   RadioSettingValueFloat(
2003
        #                       0, 999.999999, (_freq_decode
2004
        #                       (_settings.vfoofst5)/1000000.0),0.000001, 6))
2005
        # vfo350_grp.append(rs)
2006

    
2007
        rs = RadioSetting("rxtone5", "VFO 350M Rx tone",
2008
                          RadioSettingValueMap(
2009
                            TONE_MAP, _settings.rxtone5))
2010
        vfo350_grp.append(rs)
2011

    
2012
        rs = RadioSetting("txtone5", "VFO 350M Tx tone",
2013
                          RadioSettingValueMap(
2014
                            TONE_MAP, _settings.txtone5))
2015
        vfo350_grp.append(rs)
2016
        
2017
        rs = RadioSetting("power5", "VFO 350M Power",
2018
                          RadioSettingValueMap(
2019
                            POWER_MAP, _settings.power5))
2020
        vfo350_grp.append(rs)
2021

    
2022
        rs = RadioSetting("narrow5", "VFO 350M W/N",
2023
                          RadioSettingValueMap(
2024
                            BANDWIDTH_MAP, _settings.narrow5))
2025
        vfo350_grp.append(rs)
2026

    
2027
        rs = RadioSetting("mute5", "VFO 350M SP Mute",
2028
                          RadioSettingValueMap(
2029
                            MUTE_MODE_MAP, _settings.mute5))
2030
        vfo350_grp.append(rs)
2031

    
2032
        rs = RadioSetting("shft_dir5", "VFO 350M Repeater",
2033
                          RadioSettingValueBoolean(
2034
                            _settings.shft_dir5))
2035
        vfo350_grp.append(rs)
2036

    
2037
        rs = RadioSetting("compander5", "VFO 350M Compander",
2038
                          RadioSettingValueBoolean(
2039
                            _settings.compander5))
2040
        vfo350_grp.append(rs)
2041

    
2042
        rs = RadioSetting("scrambler5", "VFO 350M Descrambler",
2043
                          RadioSettingValueList(
2044
                            SCRAMBLER_LIST,
2045
                            SCRAMBLER_LIST[_settings.scrambler5]))
2046
        vfo350_grp.append(rs)
2047

    
2048
        rs = RadioSetting("am_mode5", "VFO 350M AM Mode",
2049
                          RadioSettingValueBoolean(
2050
                            _settings.am_mode5))
2051
        vfo350_grp.append(rs)
2052

    
2053
# ############################
2054
        rs = RadioSetting("vfofreq6", "VFO 850M Freq",
2055
                          RadioSettingValueFloat(
2056
                             0, 999.999999, (_freq_decode
2057
                             (_settings.vfofreq6)/1000000.0) ,0.000001, 6))
2058
        vfo850_grp.append(rs)
2059

    
2060
        # rs = RadioSetting("vfoofst6", "VFO 850M Offset",
2061
        #                   RadioSettingValueFloat(
2062
        #                       0, 999.999999, (_freq_decode
2063
        #                       (_settings.vfoofst6)/1000000.0),0.000001, 6))
2064
        # vfo850_grp.append(rs)
2065

    
2066
        rs = RadioSetting("rxtone6", "VFO 850M Rx tone",
2067
                          RadioSettingValueMap(
2068
                            TONE_MAP, _settings.rxtone6))
2069
        vfo850_grp.append(rs)
2070

    
2071
        rs = RadioSetting("txtone6", "VFO 850M Tx tone",
2072
                          RadioSettingValueMap(
2073
                            TONE_MAP, _settings.txtone6))
2074
        vfo850_grp.append(rs)
2075
        
2076
        rs = RadioSetting("power6", "VFO 850M Power",
2077
                          RadioSettingValueMap(
2078
                            POWER_MAP, _settings.power6))
2079
        vfo850_grp.append(rs)
2080

    
2081
        rs = RadioSetting("narrow6", "VFO 850M W/N",
2082
                          RadioSettingValueMap(
2083
                            BANDWIDTH_MAP, _settings.narrow6))
2084
        vfo850_grp.append(rs)
2085

    
2086
        rs = RadioSetting("mute6", "VFO 850M SP Mute",
2087
                          RadioSettingValueMap(
2088
                            MUTE_MODE_MAP, _settings.mute6))
2089
        vfo850_grp.append(rs)
2090

    
2091
        rs = RadioSetting("shft_dir6", "VFO 850M Repeater",
2092
                          RadioSettingValueBoolean(
2093
                            _settings.shft_dir6))
2094
        vfo850_grp.append(rs)
2095

    
2096
        rs = RadioSetting("compander6", "VFO 850M Compander",
2097
                          RadioSettingValueBoolean(
2098
                            _settings.compander6))
2099
        vfo850_grp.append(rs)
2100

    
2101
        rs = RadioSetting("scrambler6", "VFO 850M Descrambler",
2102
                          RadioSettingValueList(
2103
                            SCRAMBLER_LIST,
2104
                            SCRAMBLER_LIST[_settings.scrambler6]))
2105
        vfo850_grp.append(rs)
2106

    
2107
        rs = RadioSetting("am_mode6", "VFO 850M AM Mode",
2108
                          RadioSettingValueBoolean(
2109
                            _settings.am_mode6))
2110
        vfo850_grp.append(rs)
2111

    
2112
############################
2113

    
2114
        rs = RadioSetting("vfomode_b", "VFO B Working Mode",
2115
                          RadioSettingValueMap(WORKMODE_MAP,
2116
                                               _settings.vfomode_b))
2117
        vfob_grp.append(rs)
2118

    
2119
        rs = RadioSetting("vfochan_b", "VFO B Work Channel",
2120
                          RadioSettingValueInteger(1, 999,
2121
                              _chnum_decode(_settings.vfochan_b)))
2122
        vfob_grp.append(rs)
2123

    
2124
        rs = RadioSetting("vfofreq7", "VFO B Freq",
2125
                          RadioSettingValueFloat(
2126
                             0, 999.999999, (_freq_decode
2127
                             (_settings.vfofreq7)/1000000.0) ,0.000001, 6))
2128
        vfob_grp.append(rs)
2129

    
2130
        # rs = RadioSetting("vfoofst7", "VFO B Offset",
2131
        #                   RadioSettingValueFloat(
2132
        #                       0, 999.999999, (_freq_decode
2133
        #                       (_settings.vfoofst7)/1000000.0),0.000001, 6))
2134
        # vfob_grp.append(rs)
2135

    
2136
        rs = RadioSetting("rxtone7", "VFOB Rx tone",
2137
                          RadioSettingValueMap(
2138
                            TONE_MAP, _settings.rxtone7))
2139
        vfob_grp.append(rs)
2140

    
2141
        rs = RadioSetting("txtone7", "VFOB Tx tone",
2142
                          RadioSettingValueMap(
2143
                            TONE_MAP, _settings.txtone7))
2144
        vfob_grp.append(rs)
2145
        rs = RadioSetting("power7", "VFOB Power",
2146
                          RadioSettingValueMap(
2147
                            POWER_MAP, _settings.power7))
2148
        vfob_grp.append(rs)
2149
        rs = RadioSetting("narrow7", "VFOB W/N",
2150
                          RadioSettingValueMap(
2151
                            BANDWIDTH_MAP, _settings.narrow7))
2152
        vfob_grp.append(rs)
2153
        rs = RadioSetting("mute7", "VFOB SP Mute",
2154
                          RadioSettingValueMap(
2155
                            MUTE_MODE_MAP, _settings.mute7))
2156
        vfob_grp.append(rs)
2157
        rs = RadioSetting("shft_dir7", "VFOB Repeater",
2158
                          RadioSettingValueBoolean(
2159
                            _settings.shft_dir7))
2160
        vfob_grp.append(rs)
2161
        rs = RadioSetting("compander7", "VFOB Compander",
2162
                          RadioSettingValueBoolean(
2163
                            _settings.compander7))
2164
        vfob_grp.append(rs)
2165

    
2166
        rs = RadioSetting("scrambler7", "VFOB Scrambler",
2167
                          RadioSettingValueList(
2168
                            SCRAMBLER_LIST,
2169
                            SCRAMBLER_LIST[_settings.scrambler7]))
2170
        vfob_grp.append(rs)
2171

    
2172
        rs = RadioSetting("vfosquelch_b", "VFO B Squelch",
2173
                          RadioSettingValueInteger(0, 9,
2174
                              _settings.vfosquelch_b))
2175
        vfob_grp.append(rs)
2176
        rs = RadioSetting("vfostep_b", "VFO B Step",
2177
                          RadioSettingValueList(
2178
                            STEP_LIST,
2179
                            STEP_LIST[_settings.vfostep_b]))
2180
        vfob_grp.append(rs)
2181
        # rs = RadioSetting("am_mode7", "VFOB AM Mode",
2182
        #                   RadioSettingValueBoolean(
2183
        #                     _settings.am_mode7))
2184
        # vfob_grp.append(rs)
2185

    
2186
# Scan Group Settings
2187
        def _decode(lst):
2188
            _str = ''.join([chr(c) for c in lst
2189
                            if chr(c) in SCANNAME_CHARSET])
2190
            return _str
2191

    
2192
        rs = RadioSetting("scan_a_act", "Scan A Active Group",
2193
                        RadioSettingValueList(
2194
                            SCAN_GROUP_LIST,
2195
                            SCAN_GROUP_LIST[_settings.scan_a_act]))
2196
        scan_grp.append(rs)
2197
        rs = RadioSetting("scan_b_act", "Scan B Active Group",
2198
                        RadioSettingValueList(
2199
                             SCAN_GROUP_LIST,
2200
                             SCAN_GROUP_LIST[_settings.scan_b_act]))
2201
        scan_grp.append(rs)
2202
       
2203

    
2204
        for i in range(1,11):
2205
            x=str(i)
2206
            _str = _decode(eval("_settings.scanname"+x))
2207
            LOG.debug("ScanName %s",i)
2208
            LOG.debug("is %s", _str)
2209
            # CPS treats PPPPPP as a blank name as it is the factor reset value"
2210
            # The Radio treats PPPPPPP as a blank name and can display 8 chars"
2211
            # Force Chirp to blank out the scan name if value is PPPPPPP to match the radio"
2212
            # Blank out the name if first 6 are spaces or null and the 7th is a P to handle
2213
            # firmware peculiarities in handling all 8 characters.
2214
            if _str[0:7] == "PPPPPPP":
2215
                _str=""
2216
                LOG.debug("Scan name now Blank ALL P")
2217
            elif _str[0:6] =="\x00\x00\x00\x00\x00\x00":
2218
                _str=""
2219
                LOG.debug("Scan name now Blank ALL NULL")
2220
            elif _str[0:6] =="\x20\x20\x20\x20\x20\x20":
2221
                _str=""
2222
                LOG.debug("Scan name now Blank ALL SPACE")
2223
            elif (len(_str)==2) & (_str[0:2] =="PP"):
2224
                _str=""
2225
                LOG.debug("Scan name now Blank last 2 are PP")
2226
            rs=RadioSetting("scanname"+x, "Scan Name "+x,
2227
                        RadioSettingValueString(0,8, _str))
2228
            # rs = RadioSetting("scanname"+x, "Scan Name "+x, val)
2229
            scanname_grp.append(rs)
2230

    
2231
            scngrp = str(i)
2232
            rs = RadioSetting("scanlower"+scngrp, "Scan Lower "+scngrp,
2233
                            RadioSettingValueInteger(1, 999,  
2234
                            eval("_settings.scanlower"+scngrp)))
2235
            scan_grp.append(rs)
2236
            rs = RadioSetting("scanupper"+scngrp, "Scan Upper "+scngrp,
2237
                            RadioSettingValueInteger(1, 999,  
2238
                            eval("_settings.scanupper"+scngrp)))
2239
            scan_grp.append(rs)
2240
# remote settings
2241
        rs = RadioSetting("rc_power", "RC Power",
2242
                           RadioSettingValueList(
2243
                                    RC_POWER_LIST,
2244
                                    RC_POWER_LIST[_settings.rc_power]))
2245
        remote_grp.append(rs)
2246

    
2247
        _code =''
2248
        test = int(_settings.ani_edit)
2249
        _codeobj = '0x{0:0{1}X}'.format(test,6)
2250
        LOG.debug("codeobj = %s" % _codeobj)
2251
        _ani = str(_codeobj)
2252
        for i in range(2,8):
2253
            LOG.debug("ani[i] = %s" % _ani[i])
2254
            if _ani[i] in dtmfchars:
2255
                _code += _ani[i]
2256
        val_ani = int(_code)
2257
        LOG.debug("ani = %s" % val_ani)
2258
        val_ani = RadioSettingValueString(3, 6, _code, False)
2259
        val_ani.set_charset(dtmfchars)
2260
        rs = RadioSetting("settings.ani_edit", "ANI Edit", val_ani)
2261
        def apply_ani_id(setting, obj):
2262
            temp = list()
2263
            LOG.debug("val= %s" % val_ani)
2264
            if str(val_ani)[0] == "0":
2265
                raise errors.RadioError("ANI EDIT must start with Non-Zero Digit")
2266
            val2 = hex(int(str(val_ani),16))
2267
            LOG.debug("val2= %s" % val2)
2268
            if (int(val2,16) != 0):
2269
               while len(val2) < 5:
2270
                   val2 += '0'
2271
               while len(val2) < 8:
2272
                   val2 += 'C'
2273
            ani = int(str(val2),16)
2274
            LOG.debug("ani= %s" % ani)
2275
            LOG.debug("val= %s" % val_ani)
2276
            obj.ani_edit = ani
2277
        rs.set_apply_callback(apply_ani_id, _settings)
2278
        remote_grp.append(rs)
2279

    
2280
        _code =''
2281
        test = int(_settings.mcc_edit)
2282
        _codeobj = '0x{0:0{1}X}'.format(test,6)
2283
        LOG.debug("codeobj = %s" % _codeobj)
2284
        _mcc = str(_codeobj)
2285
        for i in range(2,8):
2286
            LOG.debug("mcc[i] = %s" % _mcc[i])
2287
            if _mcc[i] in dtmfchars:
2288
                _code += _mcc[i]
2289
        val_mcc = int(_code)
2290
        LOG.debug("mcc = %s" % val_mcc)
2291
        val_mcc = RadioSettingValueString(3, 6, _code, False)
2292
        val_mcc.set_charset(dtmfchars)
2293
        rs = RadioSetting("mcc_edit", "MCC Edit", val_mcc)
2294
        def apply_mcc_id(setting, obj):
2295
            val2 = hex(int(str(val_mcc),16))
2296
            LOG.debug("val2= %s" % val2)
2297
            if (int(val2,16) != 0):
2298
               while len(val2) < 5:
2299
                   val2 += '0'
2300
               while len(val2) < 8:
2301
                   val2 += 'C'
2302
            mcc = int(str(val2),16)
2303
            LOG.debug("val3= %s" % mcc)
2304
            LOG.debug("val= %s" % val_mcc)
2305
            obj.mcc_edit = mcc
2306
        rs.set_apply_callback(apply_mcc_id, _settings)
2307
        remote_grp.append(rs)
2308

    
2309
        _code =''
2310
        test = int(_settings.scc_edit)
2311
        _codeobj = '0x{0:0{1}X}'.format(test,6)
2312
        LOG.debug("codeobj = %s" % _codeobj)
2313
        _scc = str(_codeobj)
2314
        for i in range(2,8):
2315
            LOG.debug("scc[i] = %s" % _scc[i])
2316
            if _scc[i] in dtmfchars:
2317
                _code += _scc[i]
2318
        val_scc = int(_code)
2319
        LOG.debug("scc = %s" % val_scc)
2320
        val_scc = RadioSettingValueString(3, 6, _code, False)
2321
        val_scc.set_charset(dtmfchars)
2322
        rs = RadioSetting("scc_edit", "SCC Edit", val_scc)
2323
        def apply_scc_id(setting, obj):
2324
            val2 = hex(int(str(val_scc),16))
2325
            LOG.debug("val2= %s" % val2)
2326
            if (int(val2,16) != 0):
2327
               while len(val2) < 5:
2328
                   val2 += '0'
2329
               while len(val2) < 8:
2330
                   val2 += 'C'
2331
            scc = int(str(val2),16)
2332
            LOG.debug("val3= %s" % scc)
2333
            LOG.debug("val= %s" % val_scc)
2334
            obj.scc_edit = scc
2335
        rs.set_apply_callback(apply_scc_id, _settings)
2336
        remote_grp.append(rs)
2337

    
2338
        _code =''
2339
        test = int(_settings.ctrl_edit)
2340
        _codeobj = '0x{0:0{1}X}'.format(test,6)
2341
        LOG.debug("codeobj = %s" % _codeobj)
2342
        _ctrl = str(_codeobj)
2343
        for i in range(2,8):
2344
            LOG.debug("ctrl[i] = %s" % _ctrl[i])
2345
            if _ctrl[i] in dtmfchars:
2346
                _code += _ctrl[i]
2347
        val_ctrl = int(_code)
2348
        LOG.debug("ctrl = %s" % val_ctrl)
2349
        val_ctrl = RadioSettingValueString(3, 6, _code, False)
2350
        val_ctrl.set_charset(dtmfchars)
2351
        rs = RadioSetting("ctrl_edit", "CTRL Edit", val_ctrl)
2352
        def apply_ctrl_id(setting, obj):
2353
            val2 = hex(int(str(val_ctrl),16))
2354
            LOG.debug("val2= %s" % val2)
2355
            if (int(val2,16) != 0):
2356
               while len(val2) < 5:
2357
                   val2 += '0'
2358
               while len(val2) < 8:
2359
                   val2 += 'C'
2360
            ctrl = int(str(val2),16)
2361
            LOG.debug("val3= %s" % ctrl)
2362
            LOG.debug("val= %s" % val_ctrl)
2363
            obj.ctrl_edit = ctrl
2364
        rs.set_apply_callback(apply_ctrl_id, _settings)
2365
        remote_grp.append(rs)
2366

    
2367

    
2368

    
2369

    
2370

    
2371
# OEM Settings
2372

    
2373
        _oem_name = _oem_str_decode(self._memobj.oem.display_name)
2374
        rs=RadioSetting("oem.display_name", "Area Message",
2375
                        RadioSettingValueString(1,8, _oem_name))
2376
        oem_grp.append(rs)
2377

    
2378
# FM RADIO PRESETS
2379

    
2380
# memory stores raw integer value like 7600
2381
# radio will divide 7600 by 100 and interpret correctly at 76.0Mhz
2382
        #
2383
        # FM Radio Presets Settings
2384
        #
2385

    
2386
        for i in range(1, 21):
2387
            chan = str(i)
2388
            rs = RadioSetting("FM_radio" + chan, "FM Preset " + chan,
2389
                              RadioSettingValueFloat(76.0, 108.0,
2390
                                                     eval("_settings.FM_radio" +
2391
                                                          chan)/100.0,
2392
                                                     0.1, 1))
2393
            fmradio_grp.append(rs)
2394

    
2395
        return group
2396

    
2397
    def get_settings(self):
2398
        try:
2399
            return self._get_settings()
2400
        except:
2401
            import traceback
2402
            LOG.error("Failed to parse settings: %s", traceback.format_exc())
2403
            return None
2404

    
2405
    def set_settings(self, settings):
2406
        for element in settings:
2407
            if not isinstance(element, RadioSetting):
2408
                self.set_settings(element)
2409
                continue
2410
            else:
2411
                try:
2412
                    if "." in element.get_name():
2413
                        bits = element.get_name().split(".")
2414
                        obj = self._memobj
2415
                        for bit in bits[:-1]:
2416
                            obj = getattr(obj, bit)
2417
                        setting = bits[-1]
2418
                    else:
2419
                        obj = self._memobj.settings
2420
                        setting = element.get_name()
2421

    
2422
                    if element.has_apply_callback():
2423
                        LOG.debug("Using apply callback")
2424
                        element.run_apply_callback()
2425
                    else:
2426
                        LOG.debug("Setting %s = %s" % (setting, element.value))
2427
                        if self._is_freq(element):
2428
                            # setattr(obj, setting, int(element.value / 10))
2429
                            # MRT rescale freq values to match radio
2430
                            # expected values
2431
                            value = _freq_encode(element[0].get_value()*1000000.0)
2432
                            setattr(obj, setting, value)
2433

    
2434
                        elif self._is_fmradio_or_voltage(element):
2435
                            # MRT rescale FM Radio values to match radio
2436
                            # expected values
2437
                            setattr(obj, setting,
2438
                                    int(element.values()[0]._current * 100.0))
2439

    
2440
                        elif self._is_limit(element):
2441
                            setattr(obj, setting,
2442
                                    int(str(element.values()[0]._current * 10), 16))
2443
                # Special VFO A Settings
2444
                #
2445
                        elif self._is_chan(element):
2446
                            value = _chnum_encode(element[0].get_value())
2447
                            setattr(obj, setting, value)
2448
                            continue
2449
                #
2450
                        elif self._is_display_name(element):
2451
                            string=element[0].get_value()
2452
                            nameenc = _oem_str_encode(string)
2453
                            for i in range(0,8):
2454
                                LOG.debug("nameenc %s" % (nameenc[i]))
2455
                                self._memobj.oem.display_name[i] = ord(nameenc[i])
2456
                                # setattr(obj, setting, int(ord(nameenc[i])))
2457

    
2458
                        elif self._is_scan_name(element):
2459
                            string=element[0].get_value()
2460
                            LOG.debug("string %s" % (string))
2461
                            # scaname=element[0].get_name()
2462
                            # LOG.debug("scanname %s" % (scaname))
2463
                            value = _str_encode(string)
2464
                            LOG.debug("scaname %s" % (value))
2465
                            setattr(obj, setting, value)
2466
                            # self._memobj.eval(scaname)[i] = ord(nameenc[i])
2467
                            # setattr(obj, setting, int(ord(nameenc[i])))
2468
                        else:
2469
                            setattr(obj, setting, element.value)
2470
                except Exception, e:
2471
                    LOG.debug(element.get_name())
2472
                    raise
2473

    
2474
    def _is_freq(self, element):
2475
        return "rxfreq" in element.get_name() or \
2476
               "txoffset" in element.get_name() or \
2477
               "vfofreq" in element.get_name() or\
2478
               "vfoofst" in element.get_name() 
2479
        #  "rx_start" in element.get_name() or \
2480
        #  "rx_stop" in element.get_name() or \
2481
        #  "tx_start" in element.get_name() or \
2482
        #  "tx_stop" in element.get_name()
2483

    
2484
    def _is_limit(self, element):
2485
        return "limit" in element.get_name()
2486

    
2487
    def _is_fmradio_or_voltage(self, element):
2488
        return "FM_radio" in element.get_name() or\
2489
                "thr_vol_lvl" in element.get_name()
2490

    
2491
    
2492
    def _is_chan(self, element):
2493
        return "vfochan" in element.get_name() or\
2494
               "pri_ch" in element.get_name()
2495

    
2496
    def _is_display_name(self, element):
2497
        return "display_name" in element.get_name() 
2498
    
2499
    def _is_scan_name(self, element):
2500
        return "scanname" in element.get_name() 
2501
  
2502
    # def _is_vfofreq(self, element):
2503
    #     return "vfofreq" in element.get_name() or\
2504
    #            "vfoofst" in element.get_name()
(1-1/2)