-
Notifications
You must be signed in to change notification settings - Fork 245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MD2017 support #789
Comments
Excellent! I'll look into ordering one this week. |
Side note (put here for googlers) - the connector on the MD2017 is the same as on Motorola EX500, EX600, GP328, etc. Planet Headset knows it as the M5. Pryme knows it as the HYT x43. I know it is this connector because I now have an accessory meant for that group of Motorola radios that works great with the MD2017. |
I can wrap / unwrap firmware images for 2017 and flash them to the radio. Also can read/write the spi flash. I have the users DB working and most of the symbols ported to the 2017. I have yet to get the extra usb DNLOAD commands working for peek/poke but its all coming along. How can I help out? |
I use the stock updater utility to program firmware images to the 2017 as of now but I should be able to port the md380tools scripts to work without too much hassle |
I've got the encryption keystream that the 2017 / RT82 use |
@KG5RKI I'll be happy for pull requests, and I can also help merge, and/or port your C# to Python - whatever's easiest! |
alright, please just make sure I get a little credit on this.. took me many
hours to get it working..
…On Thu, Jul 6, 2017 at 3:59 PM, Mike M ***@***.***> wrote:
@KG5RKI <https://github.com/kg5rki> I'll be happy for pull requests, and
I can also port your C# back to Python - whatever's easiest!
Where can I find the keystream for the MD2017 for wrapping and unwrapping?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#789 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/Abe5494tX5vvg0l53bcDh8gzW69dn6D0ks5sLUrMgaJpZM4OPmL0>
.
|
On Thu, Jul 6, 2017 at 4:16 PM, Ty Weaver ***@***.***> wrote:
alright, please just make sure I get a little credit on this.. took me
many hours to get it working..
On Thu, Jul 6, 2017 at 3:59 PM, Mike M ***@***.***> wrote:
> @KG5RKI <https://github.com/kg5rki> I'll be happy for pull requests, and
> I can also port your C# back to Python - whatever's easiest!
> Where can I find the keystream for the MD2017 for wrapping and unwrapping?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#789 (comment)>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/Abe5494tX5vvg0l53bcDh8gzW69dn6D0ks5sLUrMgaJpZM4OPmL0>
> .
>
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from __future__ import print_function
import argparse
import binascii
import struct
import sys
class MD380FW(object):
# The stream cipher of MD-380 OEM firmware updates boils down
# to a cyclic, static XOR key block, and here it is:
key = '00aa89891f4beccf424514540065eb66417d4c88495a210df2f5c8e638edbcb9fb357133010a7f9e3b2903b6493e42b83f9f90bdaa3a7146cecdfd183255894a5fc8839ce4069e0a9d0d2fa1356dd792eafd638590cbf02fd9595327d306b8f5b2ca886cd026913bf25b61becddbf21ac9fd8d8804f4e8f19a0292bc24e990e47ea3494dce529f58c17a5fb5186edb786408d56f0d9d9fb39930817e2be65b3c4aba8be5e472118993d2f12d1e0fd9d5438704e2b4ae5e9e5f4ce916f2e65f289f7919dc1d6f2ff8efcbe1cee8a73659efe0e28800106dda73bc922b81cfe6ce0447badb7e2f41ca5dcdf6417d1c382bef7d370af9a9148e5dea4466de8b3656018c358a119b8f2a6540f72ee6582874cbc4cb0fa7629be3a63cc76f130097e91eb15390dd9b613e908cad3c29414e5b0c1f664013244900d51ce2ed281853afe41cdc96ea18fe2e6519e01450c1f10939f5cf4544d5680d72f15f8823b9b1cfda36984341f8af236d50575e62bf5aa5daadcfc5425e3e34062304e90ecdf87189674e40e925bc452e97dcc16822d25877b12e6916a8149b181a9ab8f03b71bf7718c834ea856dbb325735e569d49f4a9968b4d8c79a316a303de89cd2eb64de2eafccc84d0209ae01f92b736dbc09a2c73a28ba5d1bdfcad6f6b83ebbc518f9369623a41983da4521e386137dc25a898a8f54b9e11564e393add046b3b1d7361533956f56ef26a91c7f0e6c9fced82669cffe7b5a6f09dceec8f95bc397e7bd55f0e9d10c3036017a348b27ddc8cda2ec62efa8d01116dd70b0fb25f15f91b77d34e974442d5276c169c4eb3f987f249bb1efe94be3d3109fcd9e4e47f11d4c16665bfd06cec2307b888261cc2737d5ff22c6e6d4cc879b0687aa7bcd35d3a3a7f0081758fbcd562ff88d318c5b3cdc9f1e3b4672b77ca62a47e6568a14fbe5b839b868449cbc106621ad02871dd862030e17b12e89f85a95731b878674dc39d2a93298d199d788a76baa7cc656518fb45822d10f2b44dece7511b6c93fbfc87ca8405007da66e37a3e4b4850ecf08a3966244b1d85a85b5db3908a5c5becba3e9ea838ef48b14c6702590e2dc9fd7c1a9ee5ca607f6bf9cb9760ab46b2ab36a0f333f790c900e9f71f9d7566d3c08ce06a2cf4e102d7df9e8748c28f2a44642b0fa936f3469ae2b1fddc2602f480e31231c371a7f4323661ed127740adfe6d665bd29c1ea8c8601e04e1c9091387a8385a70eaba3fc525993084715f222379d93d76d21bd5d28bc49d730584171b04db4ffc0723c9d8d5d0b86759f770f9af0d1e5c7ff2b7008a2d2e59827aea851f82772f6fe97cb36e8ded82d60d81c93889674d4ca9359986e1215ce9f3730d20b53ad0cb143e9d1759379f91ab3cda3cd57e11e04a36e7a666dc44e2f79afa30fc00a9c2adf9e0f8bbfe8431d88976e2'.decode('hex')
def __init__(self, base_address=0x800c000):
self.magic = b'OutSecurityBin'
self.jst = b'MD-9600\x00\x00'
self.foo = '\x30\x02\x00\x30\x00\x40\x00\x47'
self.bar = ('\x02\x19\x0C\x03\x04\x05\x06\x07'
'\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
'\x10\x11\x12\x13\x14\x15\x16\x17'
'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'
'\x20')
self.foob = ('\x02\x00\x00\x00\x00\x00\x06\x00')
self.start = base_address
self.app = None
self.footer = 'OutputBinDataEnd'
self.header_fmt = '<16s9s7s16s33s43s8sLLL112s'
self.footer_fmt = '<240s16s'
self.rsrcSize = 0x5D400
def pad(self, align=512, byte=b'\xff'):
pad_length = (align - len(self.app) % align) % align
self.app += byte * pad_length
def wrap(self):
bin = b''
header = struct.Struct(self.header_fmt)
footer = struct.Struct(self.footer_fmt)
self.pad()
app = self.crypt(self.app)
bin += header.pack(
self.magic, self.jst, b'\xff' * 7, self.foo,
self.bar, b'\xff' * 43, self.foob, self.rsrcSize, self.start, len(app)-self.rsrcSize,
b'\xff' * 112)
bin += self.crypt(self.app)
bin += footer.pack(b'\xff' * 240, self.footer)
return bin
def unwrap(self, img):
header = struct.Struct(self.header_fmt)
header = header.unpack(img[:256])
self.start = header[6]
app_len = header[7]
self.app = self.crypt(img[256:256 + app_len])
assert header[0].startswith(self.magic)
assert header[1].startswith(self.jst)
assert header[3].startswith(self.foo)
assert header[4] == self.bar
assert 0x8000000 <= header[6] < 0x8200000
assert header[7] == len(img) - 512
def crypt(self, data):
return self.xor(data, self.key)
@staticmethod
def xor(a, b):
# FIXME: optimized version
out = b''
l = max(len(a), len(b))
for i in range(l):
out += chr(ord(a[i % len(a)]) ^ ord(b[i % len(b)]))
return out
def main():
def hex_int(x):
return int(x, 0)
parser = argparse.ArgumentParser(description='Wrap and unwrap MD-380 firmware')
parser.add_argument('--wrap', '-w', dest='wrap', action='store_true',
default=False,
help='wrap app into firmware image')
parser.add_argument('--unwrap', '-u', dest='unwrap', action='store_true',
default=False,
help='unwrap app from firmware image')
parser.add_argument('--addr', '-a', dest='addr', type=hex_int,
default=0x800c000,
help='base address in flash')
parser.add_argument('--offset', '-o', dest='offset', type=hex_int,
default=0,
help='offset to skip in app binary')
parser.add_argument('input', nargs=1, help='input file')
parser.add_argument('output', nargs=1, help='output file')
args = parser.parse_args()
if not (args.wrap ^ args.unwrap):
sys.stderr.write('ERROR: --wrap or --unwrap?')
sys.exit(5)
print('DEBUG: reading "%s"' % args.input[0])
with open(args.input[0], 'rb') as f:
input = f.read()
if args.wrap:
if args.offset > 0:
print('INFO: skipping 0x%x bytes in input file' % args.offset)
md = MD380FW(args.addr)
md.app = input[args.offset:]
if len(md.app) == 0:
sys.stderr.write('ERROR: seeking beyond end of input file\n')
sys.exit(5)
output = md.wrap()
print('INFO: base address 0x{0:x}'.format(md.start))
print('INFO: length 0x{0:x}'.format(len(md.app)))
elif args.unwrap:
md = MD380FW()
try:
md.unwrap(input)
except AssertionError:
sys.stderr.write('WARNING: Funky header:\n')
for i in range(0, 256, 16):
hl = binascii.hexlify(input[i:i + 16])
hl = ' '.join(hl[i:i + 2] for i in range(0, 32, 2))
sys.stderr.write(hl + '\n')
sys.stderr.write('Trying anyway.\n')
output = md.app
print('INFO: base address 0x{0:x}'.format(md.start))
print('INFO: length 0x{0:x}'.format(len(md.app)))
print('DEBUG: writing "%s"' % args.output[0])
with open(args.output[0], 'wb') as f:
f.write(output)
if __name__ == "__main__":
main()
|
Credit is no problem - git has facilities for just such an occasion, and I'll make sure to note it in the code itself. Thank you for sharing! |
Looks like a good group - makes me regret not having a facebook account. With your permission, I'll add it to the list of related communities in the README and wiki here? |
yes please. I am still learning how to use git. Whatever I share with you
you can assume I share with everyone.
…On Thu, Jul 6, 2017 at 4:53 PM, Mike M ***@***.***> wrote:
Looks like a good group - makes me regret not having a facebook account.
With your permission, I'll add it to the list of related communities in the
README and wiki here?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#789 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/Abe54xNa9XOr6DvDg9L6rkEga6mSOzkvks5sLVdRgaJpZM4OPmL0>
.
|
can you message me in google hangouts at [email protected]? If you have a md2017 I can send you my fw for the userDB. |
Roger. I'm relatively new to git myself. |
Still porting the symbols for the gps version of the radio, but so far the fw works on RT82 and md2017 with nonGPS. |
@KG5RKI check email, hangouts seems down |
I'll have some merged commits of Ty's MD2017 wrap/unwrap on my repo tomorrow (edit, maybe later), and if it works well I will push to master here. |
@travisgoodspeed Who can add some stock fw for MD2017/RT82 support to archive.org/download? I'd like to add 4 files (stock fw S003.031 S003.033, D003.031, D003.033) for my next pr to firmware_files.txt |
@travisgoodspeed @ispkorte Any suggest for the model identifier? Otherwise I'll name them MD2017_ in prefix to differ them from MD3x0/MD446 firmware versions and we continue using D/S for all versions for NonGPS/GPS like Tytera/Retevis also does for the genuine images (without adding GPS explicitly. |
FYI the donation is for DMR Track, not related to md380tools. The firmware images are hosted on facebook, not the server. |
@travis , this is a public service ; no problem |
MD2017 Symbols gfx_set_bg_color = 0x080249FD ; gfx_drawchar_pos = 0x08029BA5 ; gfx_blockfill = 0x080249FD ; gfx_select_font = 0x08029AD0 ; md380_spiflash_read = 0x080439CB ; md380_spiflash_write = 0x08043AB3 ; md380_spiflash_security_registers_read = 0x08043E0D ; md380_spiflash_disable = 0x08043A9B ; md380_spiflash_enable = 0x08043A7F ; md380_spiflash_wait = 0x08043A5D ; md380_spi_sendrecv = 0x08043A11; md380_spiflash_block_erase64k = 0x080437E9 ; md380_spiflash_sektor_erase4k = 0x080437B5 ; md380_OSMboxPost = 0x0803E711 ; md380_OSMboxPend = 0x0803E5FB ; md380_blockadr = 0x2001FB14 ; md380_dfutargetadr = 0x20001228 ; md380_dfu_state = 0x2001FE3F ; usb_upld_handle = 0x080D94BD ; usb_send_packet = 0x08079CF3 ; md380_packet = 0x2001BD20 ; dmr_call_start = 0x0804C52B ; kb_keypressed = 0x2001FB64 ; gui_opmode3 = 0x2001FE4F ; gui_opmode2 = 0x2001FDFC ; m_cntr2 = 0x2001FCC8 ; MD2017 merge.py
#this is only about half of the gfxblockfill, need to add the rest |
ported all the usb related symbols but the usb hooks are still not working. Probably just forgot something stupid, but the code is a bit different so something might have changed slightly |
Has there been any progress on this? |
I have the toolchain running and symbols ported, just have not gotten every
feature added yet. Lastheard, userdb, manual dial talkgroup. Thats about
it so far
…On Wed, Jan 3, 2018 at 11:53 AM, Richard ***@***.***> wrote:
Has there been any progress on this?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#789 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/Abe546ubBuuCxMIRHCcPI-sKg_D5UPDFks5tG76ZgaJpZM4OPmL0>
.
|
Any news/progress on MD-2017 toolz? |
Any way I could help out with porting? Still working on reading codeplugs? |
@Wferr No work done yet on reading codeplugs. I have writing MD-2017 firmware working as of a few days ago, need to merge it upstream. |
@KG5RKI has a full setup for the MD2017, including ported application code. We (md380tools) have codeplug writing to the MD2017, and I have firmware writing to the MD2017. Right now, I don't remember if I merged that up to this repo entirely - I might not have. |
@mach327 : based on your branch 'md2017', I started work on reading codeplug (I put it in a separate function). |
@OE4AMW I haven't looked at your code yet, but if it's CRC32, try the Python |
I tried already using dfu_suffix.crc() - but I haven't figured out which parts of the codeplug need to be taken into account for CRC calculation. (Neither 0..0x4022D, nor 0+rdt-header..0x4022D returns the checksum that CPS 1.22 reads out ...) |
My embedded dev experience leaves much to be desired, but is there anything I can do to help with this effort? Just got a 2017 and I'm itching to get TYToolz on there! |
You can bypass all of this if you just write it directly to spi flash. I
have made minor changes to it after dumping from flash and just writing it
back straight. Maybe I am not understanding the crc your talking about
right, but if you can convert the format of the rdf into the format it
would be raw in flash you shouldn't have a problem I would think.
…On Thu, Aug 16, 2018 at 4:37 PM OE4AMW ***@***.***> wrote:
I tried already using dfu_suffix.crc() - but I haven't figured out which
parts of the codeplug need to be taken into account for CRC calculation.
(Neither 0..0x4022D, nor 0+rdt-header..0x4022D returns the checksum that
CPS 1.22 reads out ...)
It anyhow looks strange for me that the DFU-suffix is at 0x4022D (of the
.rdt) - and not at the end of the file ...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#789 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/Abe543FtHZUwoZeGRgnSd_PhVUDWFtk8ks5uReYcgaJpZM4OPmL0>
.
|
What I wanted to achieve, is to read a RDT from the radio, that can be edited in the Tytera CPS software (which works under Linux using wine, but without USB-functionality). |
There is a discord server with beta firmwares by @KG5RKI If anyone is interested/wants download links. https://discord.gg/EHY78Uz |
The firmware by @KG5RKI is now open source at https://github.com/KG5RKI/RT82Toolz if that helps add support for the MD2017/RT82 |
I am now able the build the rt82 firmware. python has to be python2 and than |
You can look at https://github.com/DaleFarnsworth-DMR/editcp by @dalefarnsworth-dmr for inspiration, they have made some progress as well in that direction. |
Right now, I can write codeplugs (which means we can write codeplugs from Linux, running the TYT CPS in wine), and have been poking at the codeplug format. So far, it's all the same structures, everything is just shifted around for the larger memory. I also was able to fix a few minor issues (such as the DFU client crash when sending md380_custom(0xA2 0x01)).
https://github.com/mach327/md380tools/tree/md2017
Starter goals:
The text was updated successfully, but these errors were encountered: