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
|
#ifndef MD390CODEPLUG_HH
#define MD390CODEPLUG_HH
#include "dm1701_codeplug.hh"
/** Device specific implementation of the codeplug for the TyT MD-390(U/V).
*
* The codeplug consists of a single segment. It starts at address @c 0x002000 and ends at
* address @c 0x040000.
*
* @section md390cpl 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">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>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>0x002040</td> <td>0x0020f0</td> <td>0x000b0</td> <td>General settings see @c TyTCodeplug::GeneralSettingsElement.</td></tr>
* <tr><td>0x002180</td> <td>0x0059c0</td> <td>0x03840</td> <td>50 Text messages @ 0x120 bytes each, see @c TyTCodeplug::MessageElement.</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>0x008ca</td> <td>1000 contacts, see @c TyTCodeplug::ContactElement.</td></tr>
* <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>0x01ee00</td> <td>0x02e800</td> <td>0x0fa00</td> <td>1000 channels, see @c MD390Codeplug::ChannelElement.</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>
* </table>
*
* @ingroup md390 */
class MD390Codeplug : public TyTCodeplug
{
Q_OBJECT
public:
/** Extends the common @c TyTCodeplug::ChannelElement to implement the MD-390 specific settings.
*
* Memory layout of the channel (size 0x0040 bytes):
* @verbinclude md390_channel.txt */
class ChannelElement: public DM1701Codeplug::ChannelElement
{
protected:
/** Hidden constructor. */
ChannelElement(uint8_t *ptr, size_t size);
public:
/** Constructor. */
explicit ChannelElement(uint8_t *ptr);
void clear();
/** Returns @c true if the 'compressed UDP data header' is enabled. */
virtual bool compressedUDPHeader() const;
/** Enables/disables 'compressed UDP data header'. */
virtual void enableCompressedUDPHeader(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);
};
/** Extends the @c TyTCodeplug::MenuSettingsElement to implement the MD-390 specific menu settings.
*
* Memory layout of the settings (size 0x0010 bytes):
* @verbinclude md390_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 information is enabled. */
virtual bool gpsInformation() const;
/** Enables/disables GPS information menu. */
virtual void enableGPSInformation(bool enable);
bool fromConfig(const Config *config);
bool updateConfig(Config *config);
};
public:
/** Empty constructor. */
explicit MD390Codeplug(QObject *parent=nullptr);
Config *preprocess(Config *config, const ErrorStack &err) const;
bool postprocess(Config *config, const ErrorStack &err) const;
virtual bool decodeElements(Context &ctx, const ErrorStack &err=ErrorStack());
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);
void clearMenuSettings();
void clearEmergencySystems();
protected:
/** Some internal offsets within the codeplug. */
struct Offset {
/// @cond DO_NOT_DOCUMENT
static constexpr unsigned int messages() { return 0x002180; }
/// @endcond
};
};
#endif // MD390CODEPLUG_HH
|