File: uv390_codeplug.hh

package info (click to toggle)
qdmr 0.13.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 22,420 kB
  • sloc: cpp: 95,929; xml: 10,749; python: 1,108; makefile: 78; sh: 9
file content (409 lines) | stat: -rw-r--r-- 18,347 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
#ifndef UV390_CODEPLUG_HH
#define UV390_CODEPLUG_HH

#include "dm1701_codeplug.hh"

/** Device specific implementation of the codeplug for the TyT MD-UV390.
 *
 * The codeplug consists of two segments. The first segment starts at address @c 0x002000 and ends at
 * address @c 0x040000. The second segment starts at address @c 0x110000 and ends at @c 0x1a0000. The
 * segments must align with @c 0x400 (1024 bytes).
 *
 * @section uv390cpl Codeplug structure within radio
 * The codeplug structure is reverse engineered almost completely and can be programmed from
 * scratch. That is, it is not necessary to update an existing codeplug on the radio.
 * <table>
 *  <tr><th>Start</th>    <th>End</th>      <th>Size</th>    <th>Content</th></tr>
 *  <tr><th colspan="4">First segment 0x002000-0x040000</th></tr>
 *  <tr><td>0x002000</td> <td>0x00200c</td> <td>0x0000c</td> <td>Timestamp see @c TyTCodeplug::TimestampElement.</td></tr>
 *  <tr><td>0x00200c</td> <td>0x002040</td> <td>0x00034</td> <td>Reserved, filled with 0xff. </td></tr>
 *  <tr><td>0x002040</td> <td>0x0020f0</td> <td>0x000b0</td> <td>General settings see @c GeneralSettingsElement.</td></tr>
 *  <tr><td>0x0020f0</td> <td>0x002100</td> <td>0x00010</td> <td>Menu settings, see @c MenuSettingsElement.</td></tr>
 *  <tr><td>0x002100</td> <td>0x002140</td> <td>0x00040</td> <td>Button config, see @c TyTCodeplug::ButtonSettingsElement.</td></tr>
 *  <tr><td>0x002140</td> <td>0x002180</td> <td>0x00040</td> <td>Reserved, filled with 0xff.</td></tr>
 *  <tr><td>0x002180</td> <td>0x0059c0</td> <td>0x03840</td> <td>50 Text messages @ 0x120 bytes each.</td></tr>
 *  <tr><td>0x0059c0</td> <td>0x005a70</td> <td>0x000b0</td> <td>Privacy keys, see @c TyTCodeplug::EncryptionElement.</td></tr>
 *  <tr><td>0x005a70</td> <td>0x005a80</td> <td>0x00010</td> <td>Emergency system settings, see @c TyTCodeplug::EmergencySettingsElement.</td></td>
 *  <tr><td>0x005a80</td> <td>0x005f80</td> <td>0x00500</td> <td>Emergency systems, see @c TyTCodeplug::EmergencySystemElement.</td></td>
 *  <tr><td>0x005f80</td> <td>0x00ec20</td> <td>0x08ca0</td> <td>Reserved, filled with 0xff.</td></td>
 *  <tr><td>0x00ec20</td> <td>0x0149e0</td> <td>0x05dc0</td> <td>250 RX Group lists @ 0x60 bytes each, see @c TyTCodeplug::GroupListElement.</td></tr>
 *  <tr><td>0x0149e0</td> <td>0x018860</td> <td>0x03e80</td> <td>250 Zones @ 0x40 bytes each, see @c TyTCodeplug::ZoneElement.</td></tr>
 *  <tr><td>0x018860</td> <td>0x01edf0</td> <td>0x06590</td> <td>250 Scanlists @ 0x68 bytes each, see @c TyTCodeplug::ScanListElement.</td></tr>
 *  <tr><td>0x01edf0</td> <td>0x02ef00</td> <td>0x10110</td> <td>Reserved, filled with @c 0xff. </td></tr>
 *  <tr><td>0x02ef00</td> <td>0x02ef40</td> <td>0x00040</td> <td>VFO A channel, see @c VFOChannelElement.</td></tr>
 *  <tr><td>0x02ef40</td> <td>0x02ef80</td> <td>0x00040</td> <td>VFO B channel, see @c VFOChannelElement.</td></tr>
 *  <tr><td>0x02ef80</td> <td>0x02f000</td> <td>0x00080</td> <td>Reserved, filled with @c 0xff. </td></tr>
 *  <tr><td>0x02f000</td> <td>0x02f010</td> <td>0x00010</td> <td>Boot settings, see @c BootSettingsElement.</td></tr>
 *  <tr><td>0x02f010</td> <td>0x031000</td> <td>0x01ff0</td> <td>Reserved, filled with @c 0xff. </td></tr>
 *  <tr><td>0x031000</td> <td>0x03eac0</td> <td>0x0dac0</td> <td>250 Zone-extensions @ 0xe0 bytes each, see @c DM1701Codeplug::ZoneExtElement.</td></tr>
 *  <tr><td>0x03eac0</td> <td>0x03ec40</td> <td>0x00180</td> <td>Reserved, filled with @c 0xff. </td></tr>
 *  <tr><td>0x03ec40</td> <td>0x03ed40</td> <td>0x00100</td> <td>16 GPS systems @ 0x10 bytes each, see @c TyTCodeplug::GPSSystemElement.</td></tr>
 *  <tr><td>0x03ed40</td> <td>0x040000</td> <td>0x012c0</td> <td>Reserved, filled with @c 0xff. </td></tr>
 *  <tr><th colspan="4">Second segment 0x110000-0x1a0000</th></tr>
 *  <tr><td>0x110000</td> <td>0x13ee00</td> <td>0x2ee00</td> <td>3000 Channels @ 0x40 bytes each, see @c ChannelElement.</td></tr>
 *  <tr><td>0x13ee00</td> <td>0x140000</td> <td>0x01200</td> <td>Reserved, filled with @c 0xff. </td></tr>
 *  <tr><td>0x140000</td> <td>0x197e40</td> <td>0x57e40</td> <td>10000 Contacts @ 0x24 bytes each, see @c TyTCodeplug::ContactElement.</td></tr>
 *  <tr><td>0x197e40</td> <td>0x1a0000</td> <td>0x081c0</td> <td>Reserved, filled with @c 0xff. </td></tr>
 * </table>
 *
 * @ingroup uv390 */
class UV390Codeplug : public TyTCodeplug
{
  Q_OBJECT

public:
  /** Extends the @c TyTCodeplug::ChannelElement for the TyT MD-UV390 and Retevis RT3S.
   *
   * Memory layout of encoded channel:
   * @verbinclude uv390_channel.txt */
  class ChannelElement: public TyTCodeplug::ChannelElement
  {
  protected:
    /** Constructs a channel from the given memory. */
    ChannelElement(uint8_t *ptr, size_t size);

  public:
    /** Constructs a channel from the given memory. */
    explicit ChannelElement(uint8_t *ptr);

    /** Clears/resets the channel and therefore disables it. */
    void clear();

    bool talkaround() const;
    void enableTalkaround(bool enable);

    /** Returns @c true, if the privacy switch is enabled. */
    virtual bool privacySwitch() const;
    /** Enables/disables the privacy switch. */
    virtual void enablePrivacySwitch(bool enable);

    /** Overrides TyT basic implementation to enable privacy switch, whenever encryption
     *  is enabled for this channel. */
    void setPrivacyType(PrivacyType type) override;

    /** Returns the in-call criterion for this channel. */
    virtual TyTChannelExtension::InCallCriterion inCallCriteria() const;
    /** Sets the in-call criterion for this channel. */
    virtual void setInCallCriteria(TyTChannelExtension::InCallCriterion crit);

    /** Returns the remote turn-off/kill frequency for this channel. */
    virtual TyTChannelExtension::KillTone turnOffFreq() const;
    /** Sets the remote turn-off/kill frequency for this channel. */
    virtual void setTurnOffFreq(TyTChannelExtension::KillTone freq);

    /** Returns the squelch level [0-10]. */
    virtual unsigned squelch() const;
    /** Sets the squelch level [0-10]. */
    virtual void setSquelch(unsigned value);

    /** Returns the power of this channel. */
    virtual Channel::Power power() const;
    /** Sets the power of this channel. */
    virtual void setPower(Channel::Power pwr);

    /** Returns @c true if the channel allows interruption enabled. */
    virtual bool allowInterrupt() const;
    /** Enables/disables interruption for this channel. */
    virtual void enableAllowInterrupt(bool enable);

    /** Returns @c true if the channel has dual-capacity direct mode enabled. */
    virtual bool dualCapacityDirectMode() const;
    /** Enables/disables dual-capacity direct mode for this channel. */
    virtual void enableDualCapacityDirectMode(bool enable);

    /** Returns @c true if the radio acts as the leader for this DCDM channel. */
    virtual bool dcdmLeader() const;
    /** Enables/disables this radio to be the leader for this DCDM channel. */
    virtual void enableDCDMLeader(bool enable);

    /** Constructs a generic @c Channel object from the codeplug channel. */
    virtual Channel *toChannelObj(const ErrorStack &err=ErrorStack()) const;
    /** Initializes this codeplug channel from the given generic configuration. */
    virtual void fromChannelObj(const Channel *c, Context &ctx);

  protected:
    /** Some internal offsets. */
    struct Offset: public TyTCodeplug::ChannelElement::Offset {
      /// @cond DO_NOT_DOCUMENT
      static constexpr Bit privacySwitch()          { return {0x0005, 2}; }
      static constexpr Bit inCallCriteria()         { return {0x0005, 4}; }
      static constexpr Bit turnOffFreq()            { return {0x0005, 6}; }
      static constexpr unsigned int squelch()       { return 0x000f; }
      static constexpr Bit power()                  { return {0x001e, 0}; }
      static constexpr Bit allowInterrupt()         { return {0x001f, 2}; }
      static constexpr Bit dualCapacityDirectMode() { return {0x001f, 3}; }
      static constexpr Bit dcdmLeader()             { return {0x001f, 4}; }
      /// @endcond
    };
  };

  /** Implements a VFO channel for TyT radios.
   * This class is an extension of the normal ChannelElement that only implements the step-size
   * feature and encodes it where the name used to be. Thus the memory layout and size is identical
   * to the normal channel. */
  class VFOChannelElement: public ChannelElement
  {
  protected:
    /** Constructor from pointer to memory. */
    VFOChannelElement(uint8_t *ptr, size_t size);

  public:
    /** Constructor from pointer to memory. */
    VFOChannelElement(uint8_t *ptr);
    /** Destructor. */
    virtual ~VFOChannelElement();

    QString name() const;
    void setName(const QString &txt);

    /** Returns the step-size for the VFO channel. */
    virtual unsigned stepSize() const;
    /** Sets the step-size for the VFO channel in Hz. */
    virtual void setStepSize(unsigned ss_hz);
  };

  /** Reuse zone extension from DM1701. */
  typedef DM1701Codeplug::ZoneExtElement ZoneExtElement;

  /** Extends the common @c TyTCodeplug::GeneralSettings to implement the MD-UV390 specific
   * settings.
   *
   * Memory layout of the settings (size 0x00b0 bytes):
   * @verbinclude uv390_settings.txt */
  class GeneralSettingsElement: public DM1701Codeplug::GeneralSettingsElement
  {
  protected:
    /** Hidden constructor. */
    GeneralSettingsElement(uint8_t *ptr, size_t size);

  public:
    /** Constructor. */
    GeneralSettingsElement(uint8_t *ptr);

    void clear();

    /** Defines all possible transmit modes. */
    enum TransmitMode {
      LAST_CALL_CH = 0,
      LAST_CALL_AND_HAND_CH = 1,
      DESIGNED_CH = 2,
      DESIGNED_AND_HAND_CH = 3,
    };

    /** Returns the transmit mode. */
    virtual TransmitMode transmitMode() const;
    /** Sets the transmit mode. */
    virtual void setTransmitMode(TransmitMode mode);

    /** Returns @c true, if the speech synthesis is enabled. */
    virtual bool channelVoiceAnnounce() const;
    /** Enables/disables the speech synthesis. */
    virtual void enableChannelVoiceAnnounce(bool enable);

    /** Returns @c true, if keypad tones are enabled. */
    virtual bool keypadTones() const;
    /** Enables/disables the keypad tones. */
    virtual void enableKeypadTones(bool enable);

    /** Returns @c true, if public zone is enabled. */
    virtual bool publicZone() const;
    /** Enables/disables public zone. */
    virtual void enablePublicZone(bool enable);

    /** Returns the n-th DMR id. */
    virtual uint32_t additionalDMRId(unsigned n) const;
    /** Sets the n-th DMR id. */
    virtual void setAdditionalDMRId(unsigned n, uint32_t id);

    /** Returns the microphone gain. */
    virtual unsigned micLevel() const;
    /** Sets the microphone gain. */
    virtual void setMICLevel(unsigned val);

    /** If @c true, radio ID editing is enabled. */
    virtual bool editRadioID() const;
    /** Enable/disable radio ID editing. */
    virtual void enableEditRadioID(bool enable);

    /** Encodes the general settings. */
    virtual bool fromConfig(const Config *config);
    /** Updates config from general settings. */
    virtual bool updateConfig(Config *config);
  };

  /** Represents the boot-time settings (selected zone and channels) within the UV390 code-plug.
   *
   * Memory layout of encoded boot settings:
   * @verbinclude uv390_bootsettings.txt */
  class BootSettingsElement: public Codeplug::Element
  {
  protected:
    /** Hidden constructor. */
    BootSettingsElement(uint8_t *ptr, size_t size);

  public:
    /** Constructor. */
    explicit BootSettingsElement(uint8_t *ptr);
    /** Destructor. */
    virtual ~BootSettingsElement();

    void clear();

    /** Returns the boot zone index. */
    virtual unsigned zoneIndex() const;
    /** Sets the boot zone index. */
    virtual void setZoneIndex(unsigned idx);
    /** Returns the channel index (within zone) for VFO A. */
    virtual unsigned channelIndexA() const;
    /** Sets the channel index (within zone) for VFO A. */
    virtual void setChannelIndexA(unsigned idx);
    /** Returns the channel index (within zone) for VFO B. */
    virtual unsigned channelIndexB() const;
    /** Sets the channel index (within zone) for VFO B. */
    virtual void setChannelIndexB(unsigned idx);
  };

  /** Represents the menu settings (selected zone and channels) within the UV390 code-plug.
   *
   * Memory layout of encoded boot settings:
   * @verbinclude uv390_menusettings.txt */
  class MenuSettingsElement: public TyTCodeplug::MenuSettingsElement
  {
  protected:
    /** Hidden constructor. */
    MenuSettingsElement(uint8_t *ptr, size_t size);

  public:
    /** Constructor. */
    explicit MenuSettingsElement(uint8_t *ptr);

    void clear();

    /** Returns @c true if GPS settings menu is enabled. */
    virtual bool gpsSettings() const;
    /** Enables/disables GPS settings menu. */
    virtual void enableGPSSettings(bool enable);
    /** Returns @c true if recording menu is enabled. */
    virtual bool recording() const;
    /** Enables/disables recording menu. */
    virtual void enableRecording(bool enable);

    /** Returns @c true if group call match menu is enabled. */
    virtual bool groupCallMatch() const;
    /** Enables/disables group call match menu. */
    virtual void enableGroupCallMatch(bool enable);
    /** Returns @c true if private call match menu is enabled. */
    virtual bool privateCallMatch() const;
    /** Enables/disables private call match menu. */
    virtual void enablePrivateCallMatch(bool enable);
    /** Returns @c true if menu hang time item is enabled. */
    virtual bool menuHangtimeItem() const;
    /** Enables/disables menu hang time item. */
    virtual void enableMenuHangtimeItem(bool enable);
    /** Returns @c true if TX mode menu is enabled. */
    virtual bool txMode() const;
    /** Enables/disables TX mode menu. */
    virtual void enableTXMode(bool enable);
    /** Returns @c true if zone settings menu is enabled. */
    virtual bool zoneSettings() const;
    /** Enables/disables zone settings menu. */
    virtual void enableZoneSettings(bool enable);
    /** Returns @c true if new zone menu is enabled. */
    virtual bool newZone() const;
    /** Enables/disables new zone menu. */
    virtual void enableNewZone(bool enable);

    /** Returns @c true if edit zone menu is enabled. */
    virtual bool editZone() const;
    /** Enables/disables edit zone menu. */
    virtual void enableEditZone(bool enable);
    /** Returns @c true if new scan list menu is enabled. */
    virtual bool newScanList() const;
    /** Enables/disables new scan list menu. */
    virtual void enableNewScanList(bool enable);
  };


public:
  /** Constructor. */
  explicit UV390Codeplug(QObject *parent = nullptr);
  /** Destructor. */
  virtual ~UV390Codeplug();

  void clear();

public:
  void clearTimestamp();
  bool encodeTimestamp();

  void clearGeneralSettings();
  bool encodeGeneralSettings(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool decodeGeneralSettings(Config *config, const ErrorStack &err=ErrorStack());

  void clearChannels();
  bool encodeChannels(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool createChannels(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
  bool linkChannels(Context &ctx, const ErrorStack &err=ErrorStack());

  void clearContacts();
  bool encodeContacts(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool createContacts(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());

  void clearZones();
  bool encodeZones(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool createZones(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
  bool linkZones(Context &ctx, const ErrorStack &err=ErrorStack());

  void clearGroupLists();
  bool encodeGroupLists(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool createGroupLists(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
  bool linkGroupLists(Context &ctx, const ErrorStack &err=ErrorStack());

  void clearScanLists();
  bool encodeScanLists(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool createScanLists(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
  bool linkScanLists(Context &ctx, const ErrorStack &err=ErrorStack());

  void clearPositioningSystems();
  bool encodePositioningSystems(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool createPositioningSystems(Config *config, Context &ctx, const ErrorStack &err=ErrorStack());
  bool linkPositioningSystems(Context &ctx, const ErrorStack &err=ErrorStack());

  void clearButtonSettings();
  bool encodeButtonSettings(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err=ErrorStack());
  bool decodeButtonSetttings(Config *config, const ErrorStack &err=ErrorStack());

  void clearPrivacyKeys();
  bool encodePrivacyKeys(Config *config, const Flags &flags, Context &ctx, const ErrorStack &err);
  bool decodePrivacyKeys(Config *config, Context &ctx, const ErrorStack &err);

  void clearTextMessages();
  bool encodeTextMessages(Context &ctx, const Flags &flags, const ErrorStack &err);
  bool decodeTextMessages(Context &ctx, const ErrorStack &err);

  /** Resets the boot setting, e.g. initial channels and zone at bootup. */
  virtual void clearBootSettings();
  void clearMenuSettings();
  void clearEmergencySystems();
  /** Clears the VFO A & B. */
  virtual void clearVFOSettings();

public:
  /** Some limits for the codeplug. */
  struct Limit: public Element::Limit {
    /// Number of channels.
    static constexpr unsigned int channels() { return 3000; }
  };

protected:
  /** Some internal offsets within the codeplug. */
  struct Offset {
    /// @cond DO_NOT_DOCUMENT
    static constexpr unsigned int messages() { return 0x002180; }
    static constexpr unsigned int channels() { return 0x110000; }
    static constexpr unsigned int betweenChannels() { return ChannelElement::size(); }
    /// @endcond
  };
};

#endif // UV390CODEPLUG_HH