#!/usr/bin/env python
# This program connects to a Nokia Phone using Symbian 9 and tries to set the flag to allow all permissions
# it needs MetroTRK driver to be running on mobile, and a connection between PC and phone
# Read instructions.txt for details
# History: 2008.03.13 v0.2a Work on UIQ3 (Tested on SE P1i, FW R6G04).
#                           Includes timeout for the reading of serial port (1s.)
#                           First will be tested address 0x60000148 and after this, when nothing found, will be scaned a memory.
#                           Modified by SW (swmail)
# History: 2008.03.08 v0.2 Doesn't need to run HelloCarbide.exe because now uses the ekern thread.
#                          Also includes an example to dump memory into a file
#                          Also tries to read memory using DS_MSG_MEMORY_PROTECTED+DS_MSG_MEMORY_SEGMENTED . With and without a process. Let's see if it works
# History: 2008.03.10 v0.1 Includes a memory scan to try to find the address in FP1 (N95, N82, ...)
# History: 2008.03.08 v0.0
# License: GPL. Please contact me if you make corrections
# Author: FCA00000-at-yahoo-dot-es

import serial

debug=0

def decodeFrame(myBytes): # [01 01 fd]
    sindex=0
    nack=-1
    ack=-1
    for i in myBytes:
        if (sindex==1):
            if (debug>=0): print "received message number %02X"%i
        if (i!=-1):
            if (debug>3): print "decodeFrame-i:%i"%i
        if (nack==2):
            nack=-1
            ack=-1
            if (i==0x00):
                print " kDSReplyNoError"
            if (i==0x01):
                print " kDSReplyError"
            if (i==0x02):
                print " kDSReplyPacketSizeError"
            if (i==0x03):
                print " kDSReplyCWDSError"
            if (i==0x04):
                print " kDSReplyEscapeError"
            if (i==0x05):
                print " kDSReplyBadFCS"
            if (i==0x06):
                print " kDSReplyOverflow"
            if (i==0x07):
                print " kDSReplySequenceMissing"
            if (i==0x10):
                print " kDSReplyUnsupportedCommandError"
            if (i==0x11):
                print " kDSReplyParameterError"
            if (i==0x12):
                print " kDSReplyUnsupportedOptionError"
            if (i==0x13):
                print " kDSReplyInvalidMemoryRange"
            if (i==0x14):
                print " kDSReplyInvalidRegisterRange"
            if (i==0x15):
                print " kDSReplyCWDSException"
            if (i==0x16):
                print " kDSReplyNotStopped"
            if (i==0x17):
                print " kDSReplyBreakpointsFull"
            if (i==0x18):
                print " kDSReplyBreakpointConflict"
            if (i==0x20):
                print " kDSReplyOsError"
            if (i==0x21):
                print " kDSReplyInvalidProcessId"
            if (i==0x22):
                print " kDSReplyInvalidThreadId"
        if (nack==1):
            nack=2
        if (ack==1):
            nack=2
        if (sindex==0):
            if (i==0x00):
                print "<kDSPing"
            if (i==0x01):
                print "<kDSConnect"
            if (i==0x02):
                print "<kDSDisconnect"
            if (i==0x03):
                print "<kDSReset"
            if (i==0x04):
                print "<kDSVersions"
            if (i==0x05):
                print "<kDSSupportMask"
            if (i==0x06):
                print "<kDSCPUType"
            if (i==0x07):
                print "<kDSConfigTransport"
            if (i==0x10):
                print "<kDSReadMemory"
            if (i==0x11):
                print "<kDSWriteMemory"
            if (i==0x12):
                print "<kDSReadRegisters"
            if (i==0x13):
                print "<kDSWriteRegisters"
            if (i==0x14):
                print "<kDSFillMemory"
            if (i==0x15):
                print "<kDSCopyMemory"
            if (i==0x16):
                print "<kDSFlushCache"
            if (i==0x18):
                print "<kDSContinue"
            if (i==0x19):
                print "<kDSStep"
            if (i==0x1a):
                print "<kDSStop"
            if (i==0x1b):
                print "<kDSSetBreak"
            if (i==0x1c):
                print "<kDSClearBreak"
            if (i==0x1d):
                print "<kDSDownload"
            if (i==0x1e):
                print "<kDSModifyBreakThread"
            if (i==0x20):
                print "<kDSNotifyFileInput"
            if (i==0x21):
                print "<kDSBlockFileIo"
            if (i==0x40):
                print "<kDSOSCreateItem"
            if (i==0x41):
                print "<kDSOSDeleteItem" # ProcessID: 0x000000F7 (247)   41 DD 00 00 00 00 00 F7
            if (i==0x42):
                print "<kDSOSReadInfo"
            if (i==0x43):
                print "<kDSOSWriteInfo"

            if (i==0x80):
                print "<kDSReplyACK"
                ack=1
            if (i==0xFF):
                print "<kDSReplyNAK !!!!!!!!!!!!!!!!!!"
                nack=1

        else:
            if (i!=-1):
                if (debug>3): print "not 1st byte %02X"%i
        sindex=sindex+1
        previ=i

def showFrameChecksum(myBytes): # [01 01 fd]
    ck = 0
    previ=-1
    for i in myBytes:
        # print "showFrameChecksum-i:%i"%i
        if (i==-1):
            if (debug>4): print "showFrameChecksum-ck=%02X previ=%02X"%(ck,previ)
            if (ck!=0xFF):
                print "showFrameChecksum-incorrect:%i"%i
            else:
                if (debug>1):
                    print "showFrameChecksum-correct:%i"%i
            break
        else:
            ck=ck+i
            if (ck>255):
                ck=ck-256
        previ=i

        
def makeFrameChecksum(myBytes): # [01 01 ??]
    ck = 0
    for i in myBytes:
        # print "makeFrameChecksum-i:%i"%(i)
        if (i>=32 and i<127):
            if (debug>2): print "makeFrameChecksum-i:              %c"%(chr(i))
        if (i==-1):
            if (debug>2): print "makeFrameChecksum-ck=%02X return=%02X"%(ck,0xFF-ck)
            return 0xFF-ck
        else:
            ck=ck+i
            if (ck>255):
                ck=ck-256
    if (debug>2): print "makeFrameChecksum-end-ck=%02X return=%02X"%(ck,0xFF-ck)
    return 0xFF-ck

def sendFrame(ser,myBytes):
    for i in myBytes:
        if (i!=-1):
            if (debug>3): print "sendFrame=%02X"%(i)
            ser.write(chr(i))

def encodeHeaderCKFrame(myBytes): # [01 01] -> [7e 01 01 fd 7e]
    ck = makeFrameChecksum(myBytes)
    sindex=0
    myBytes2=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
    myBytes2=myBytes2+myBytes2+myBytes2+myBytes2
    myBytes2=myBytes2+myBytes2+myBytes2+myBytes2
    myBytes2[sindex]=0x7e
    if (debug>=0): print "sending message number %02X"%(myBytes[1])
    for i in myBytes:
        if (i==-1):
            if (debug>2): print "encodeHeaderCKFrame-ck=%02X"%(ck)
            if (ck==0x7e or ck==0x7d):
                myBytes2[sindex+1]=0x7d
                sindex=sindex+1
                ck=ck^0x20
            myBytes2[sindex+1]=ck
            myBytes2[sindex+2]=0x7e
            myBytes2[sindex+3]=-1
            if (debug>2): print myBytes2
            return myBytes2
        else:
            if (i==0x7e or i==0x7d):
                myBytes2[sindex+1]=0x7d
                sindex=sindex+1
                i=i^0x20
        myBytes2[sindex+1]=i
        sindex=sindex+1
    # this never happens because the message ends with -1
    print "encodeHeaderCKFrame-this message does not finish with  -1  !!!!!!!!!!1"
    return [0]

def showFrameBytes(myBytes): # [7e, 01, 01, fd, 7e]
    if (debug>2): print "showFrameBytes:%s"%myBytes
    sindex=-1
    previ=-1
    escaped=-1
    myBytes2=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
    myBytes2=myBytes2+myBytes2+myBytes2+myBytes2
    myBytes2=myBytes2+myBytes2+myBytes2+myBytes2
    for i in myBytes:
        if (debug>3): print "showFrameBytes-i:%i"%i
        if (i==-1):
            if (previ!=0x7e):
                print "Frame does not end with 0x7E:%02X"%previ
            myBytes2[sindex-1]=-1
            break;
        if (previ==-1):
            if (i!=0x7e):
                print "Frame does not start with 0x7E:%02X"%i
                break;
        if (sindex>0 and (previ==0x7e or previ==0x7d)):
            escaped=1
            if (debug>2): print "XOR: i=%02X  previ=%02X  xor=%02X "%(i, previ, i^0x20)
            i=i^0x20
            sindex=sindex-1
            previ=1 # anything
        if (sindex>=0):
            myBytes2[sindex]=i
        if (escaped==-1):
            previ=i
        sindex=sindex+1
        escaped=-1
    if (debug>3): print myBytes2
    showFrameChecksum(myBytes2)
    decodeFrame(myBytes2)
    return myBytes2
    
def showFrameHex(myString): # "[7e 01 01 fd 7e]"
    if (debug>3): print "showFrameHex:%s"%myString
    vh=-1
    sindex=-1
    myBytes=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
    myBytes=myBytes+myBytes+myBytes+myBytes
    myBytes=myBytes+myBytes+myBytes+myBytes
    for i in range(0, len(myString)):
        if (debug>2): print "showFrameHex-i:%c"%myString[i]
        c = myString[i]
        if (c=='a'): c='A'
        if (c=='b'): c='B'
        if (c=='c'): c='C'
        if (c=='d'): c='D'
        if (c=='e'): c='E'
        if (c=='f'): c='F'
        v=-1
        if (c=='0'): v=0
        if (c=='1'): v=1
        if (c=='2'): v=2
        if (c=='3'): v=3
        if (c=='4'): v=4
        if (c=='5'): v=5
        if (c=='6'): v=6
        if (c=='7'): v=7
        if (c=='8'): v=8
        if (c=='9'): v=9
        if (c=='A'): v=10
        if (c=='B'): v=11
        if (c=='C'): v=12
        if (c=='D'): v=13
        if (c=='E'): v=14
        if (c=='F'): v=15
        if (debug>3): print "showFrameHex-c=v:%c=%i"%(c,v)
        if (vh>-1):
            vh=vh+v
            if (debug>3): print "showFrameHex-b:%02X"%(vh)
            sindex=sindex+1
            myBytes[sindex]=vh
            vh=-1
        else:       vh=v*16
        
    if (debug>5): print "showFrameHex-myBytes:%s"%(myBytes)
    return showFrameBytes(myBytes)
    
def showFrameBin(myString): # [7e 01 01 fd 7e]
    # print "showFrameBin:%s"%myString # It is binary, so expect weird characters
    sindex=0
    myBytes=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
    myBytes=myBytes+myBytes+myBytes+myBytes
    myBytes=myBytes+myBytes+myBytes+myBytes
    for i in range(0, len(myString)):
        if (debug>3): print "showFrameHex-i at sindex=%i:%02X"%(sindex,ord(myString[i]))
        myBytes[sindex] = ord(myString[i])
        sindex=sindex+1
    myBytes[sindex] = -1
    return showFrameBytes(myBytes)

# This is the port minus 1. If you have COM4, then use Serial(3)
ser = serial.Serial(x) # I have COM4
ser.timeout = 1     	#required so that the reader thread can exit
print "Using port:"
print ser.portstr
iCommand=0
iSendFullMessages=0

# by default, use process=ekern.exe[100041af]0001 and thread called 'Supervisor'; unless c:\HelloCarbide.exe is started
ProcessIDh=0x00
ProcessIDl=0x01
ThreadIDh=0x00
ThreadIDl=0x1

candidateAddress=0

print ">Ping"
sendFrame(ser,encodeHeaderCKFrame([0x00,iCommand,-1]))
s = ser.read(10)	# Ping get
myBytes=showFrameBin(s)
if (debug>2): print myBytes
iCommand=iCommand+1

print ">Connect"
sendFrame(ser,encodeHeaderCKFrame([0x01,iCommand,-1]))  # Connect
s = ser.read(10)	# Connect get
myBytes=showFrameBin(s)
if (debug>2): print myBytes
iCommand=iCommand+1

DS_PROTOCOL=3 # by default, although can be read and verified 

if (1==1):
    print ">SupportMask"
    sendFrame(ser,encodeHeaderCKFrame([0x05,iCommand,-1]))  # SupportMask
    s = ser.read(40)	# SupportMask get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1
    DS_PROTOCOL=myBytes[0+32+3]
    if (myBytes[0+32+3]==1):
        print "Level=DS_PROTOCOL_MIN. (required)"
    if (myBytes[0+32+3]==2):
        print "Level=DS_PROTOCOL_BOARD. (extended board-level debugger)"
    if (myBytes[0+32+3]==3):
        print "Level=DS_PROTOCOL_RTOS. (OS-level debugger)"

if (iSendFullMessages==1):
    print ">CPUType"
    sendFrame(ser,encodeHeaderCKFrame([0x06,iCommand,-1]))  # CPUType
    s = ser.read(40)	# CPUType get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1

kDSOSProcessList	= 0x0000
kDSOSProcessState	= 0x0001
kDSOSThreadList		= 0x0002
kDSOSThreadState	= 0x0003
kDSOSDLLList		= 0x0004    # This gives error kDSReplyUnsupportedOptionError
kDSOSDLLState		= 0x0005

if (iSendFullMessages==1):
    print ">Read Info: list threads for process:%02X %02X"%(ProcessIDh,ProcessIDl)
    sendFrame(ser,encodeHeaderCKFrame([0x42,iCommand,0x00,kDSOSThreadList,0x00,0x00,0x00,0x00,0x00,0x00,0x00,ProcessIDh,ProcessIDl,-1]))  # Read Info
    s = ser.read(1400)
    myBytes=showFrameBin(s)
    thisListItem=""
    for j in myBytes:
        if (j>=32 and j<=128):
            # print "Info: %c"%(chr(j))
            thisListItem=thisListItem+chr(j)
        if (j==0):
            if (len(thisListItem)>1):
                print "List item: %s"%(thisListItem)
            thisListItem=""
    if (debug>2): print myBytes
    iCommand=iCommand+1
    s = ser.read(1400)  # there might be more processes/threads/DLLs but I don't care. Just clean the rubbish
    s = ser.read(1400)
    s = ser.read(1400)
    
if (iSendFullMessages==1):
    print ">Open File"
    # C:\HelloCarbide.exe
    sendFrame(ser,encodeHeaderCKFrame([0x4A,iCommand,0x10,0x00,0x13,0x43,0x3A,0x5C,0x48,0x65,0x6C,0x6C,0x6F,0x43,0x61,0x72,0x62,0x69,0x64,0x65,0x2E,0x65,0x78,0x65,-1]))  # Open File
    s = ser.read(40)	# Open File get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1
    someData0=myBytes[7]
    someData1=myBytes[8]
    someData2=myBytes[9]
    someData3=myBytes[10]
    someData4=myBytes[11]

if (iSendFullMessages==1):
    print ">Close File"
    sendFrame(ser,encodeHeaderCKFrame([0x4B,iCommand,0x00,0x00,0x00,someData0,someData1,someData2,someData3,someData4,-1]))  # Close File
    s = ser.read(40)	# Close File get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1

if (iSendFullMessages==1):
    print ">Create Item"
    # C:\sys\bin\HelloCarbide.exe
    # sendFrame(ser,encodeHeaderCKFrame([0x4a,iCommand,0x10,0x00,0x1B,0x43 ,0x3A ,0x5C ,0x73 ,0x79 ,0x73 ,0x5C ,0x62 ,0x69 ,0x6E ,0x5C,0x48,0x65,0x6C,0x6C,0x6F,0x43,0x61,0x72,0x62,0x69,0x64,0x65,0x2E,0x65,0x78,0x65, -1]))  # Create Item
    # C:\HelloCarbide.exe
    sendFrame(ser,encodeHeaderCKFrame([0x40,iCommand,0x00,0x00,0x00,0x00,0x15,0x43,0x3A,0x5C,0x48,0x65,0x6C,0x6C,0x6F,0x43,0x61,0x72,0x62,0x69,0x64,0x65,0x2E,0x65,0x78,0x65,0x00,0x00,-1]))  # Create Item
    s = ser.read(40)	# Create Item get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1
    ProcessIDh=myBytes[5]
    ProcessIDl=myBytes[6]
    ThreadIDh=myBytes[9]
    ThreadIDl=myBytes[10]
print "ProcessID=%02X%02X ThreadID=%02X%02X "%(ProcessIDh,ProcessIDl,ThreadIDh,ThreadIDl)
    
if (iSendFullMessages==1):
    print ">Continue"
    sendFrame(ser,encodeHeaderCKFrame([0x18,iCommand,0x00,0x00,ProcessIDh,ProcessIDl,0x00 ,0x00,ThreadIDh,ThreadIDl,-1]))  # Continue
    s = ser.read(400)	# Ack get + Notify Created get  ... size=(3)+(>40) ... should extract messageID and ack it
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1

    print ">Ack Notify Created"
    sendFrame(ser,encodeHeaderCKFrame([0x80,0x01,0x00,-1]))  # Ack Notify Created
    s = ser.read(40)	# There is no answer, but clean buffer
    # myBytes=showFrameBin(s)
    # print myBytes
    # iCommand=iCommand+1

if (iSendFullMessages==1):
    print ">Read Info 0x60000000"
    sendFrame(ser,encodeHeaderCKFrame([0x42,iCommand,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x16,-1]))  # Read Info
    s = ser.read(1400)	# Read Info get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    s = ser.read(1400)	# Read Info get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    s = ser.read(1400)	# Read Info get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    s = ser.read(1400)	# Read Info get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1

DS_MSG_MEMORY_SEGMENTED	=0x01		# non-flat addr space
DS_MSG_MEMORY_EXTENDED	=0x02		# > 32-bit data addr
DS_MSG_MEMORY_PROTECTED	=0x04		# non-user memory
DS_MSG_MEMORY_USERVIEW	=0x08		# breakpoints are invisible
readSize=0x1    # *256

if (1==1):
    print "Read memory without process. Only when DS_PROTOCOL<3 . In this case, DS_PROTOCOL=%02X"%(DS_PROTOCOL)
    readAddress=0x60
    sendFrame(ser,encodeHeaderCKFrame([0x1A,iCommand,DS_MSG_MEMORY_PROTECTED,0x00,readSize,0x00,0x00,0,readAddress,-1]))  # Stop
    s = ser.read(400)
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1

if (1==1):
    print "Read Memory SEGMENTED without process. Only when DS_PROTOCOL<3 . In this case, DS_PROTOCOL=%02X"%(DS_PROTOCOL)
    readAddress=0x60
    sendFrame(ser,encodeHeaderCKFrame([0x1A,iCommand,DS_MSG_MEMORY_SEGMENTED,0x00,readSize,0x00,0x00,0,readAddress,-1]))  # Stop
    s = ser.read(400)
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1

if (1==0):
    print ">Dump memory "
    readAddressStart=0x60000000
    readAddressEnd=readAddressStart+0x300
    dumpFile=open('file.dmp', 'wb')
    for randomAddressBase in range(0,(readAddressEnd-readAddressStart)/256):
        randomAddressOffset=0
        if (1==1):
            if (randomAddressBase>=0 and randomAddressOffset>=0):
                readAddress=readAddressStart+randomAddressBase*256
                readAddress0=readAddress/(256*256*256)
                readAddress1=(readAddress-readAddress0*256*256*256)/(256*256)
                readAddress2=(readAddress-readAddress0*256*256*256-readAddress1*256*256)/(256)
                readAddress3=(readAddress-readAddress0*256*256*256-readAddress1*256*256-readAddress2*256)/(1)
                sendFrame(ser,encodeHeaderCKFrame([0x10,iCommand,DS_MSG_MEMORY_PROTECTED+DS_MSG_MEMORY_SEGMENTED,readSize, 0x00, readAddress0,readAddress1,readAddress2,readAddress3 ,0x00,0x00, ProcessIDh,ProcessIDl ,0x00,0x00, ThreadIDh,ThreadIDl,-1]))  # Read Memory
                s = ser.read(400)	# Read Memory get
                myBytes=showFrameBin(s)
                if (debug>2): print myBytes
                iCommand=iCommand+1
                if (myBytes[2]==0x20): # kDSReplyOsError
                    print "The OS reported an error :-("
                else:
                    for i in range(0,readSize*256/4):
                        data0=myBytes[5+i*4+0]
                        data1=myBytes[5+i*4+1]
                        data2=myBytes[5+i*4+2]
                        data3=myBytes[5+i*4+3]
                        print "Read Memory %08X=%02X %02X %02X %02X"%(readAddress+i*4,data0,data1,data2,data3)
                        dumpFile.write(chr(data0))
                        dumpFile.write(chr(data1))
                        dumpFile.write(chr(data2))
                        dumpFile.write(chr(data3))
    dumpFile.close()

if (1==1):
    print ">Test 0x6xxxxxxx"
    randomAddressBase=0x60000000
    randomAddressOffset=0x148
    if (randomAddressBase>=0 and randomAddressOffset>=0):
        readAddress=randomAddressBase+randomAddressOffset
        readAddress0=readAddress/(256*256*256)
        readAddress1=(readAddress-readAddress0*256*256*256)/(256*256)
        readAddress2=(readAddress-readAddress0*256*256*256-readAddress1*256*256)/(256)
        readAddress3=(readAddress-readAddress0*256*256*256-readAddress1*256*256-readAddress2*256)/(1)
        print "Read Memory at %08X=%02X %02X %02X %02X"%(readAddress,readAddress0,readAddress1,readAddress2,readAddress3)
        sendFrame(ser,encodeHeaderCKFrame([0x10,iCommand,DS_MSG_MEMORY_PROTECTED+DS_MSG_MEMORY_SEGMENTED,readSize, 0x00, readAddress0,readAddress1,readAddress2,readAddress3 ,0x00,0x00, ProcessIDh,ProcessIDl ,0x00,0x00, ThreadIDh,ThreadIDl,-1]))  # Read Memory
        s = ser.read(400)	# Read Memory get
        myBytes=showFrameBin(s)
        if (debug>2): print myBytes
        iCommand=iCommand+1
        if (myBytes[2]==0x20): # kDSReplyOsError
            print "The OS reported an error :-("
        else:
            mistakes=0
            for i in range(0,readSize*256/256):	# 256/4
                data0=myBytes[5+i*4+0]
                data1=myBytes[5+i*4+1]
                data2=myBytes[5+i*4+2]
                data3=myBytes[5+i*4+3]
                print "Read Memory %08X=%02X %02X %02X %02X"%(readAddress+i*4,data0,data1,data2,data3)
                if (i<=7 and data0==-1 and data1==-1 and data2==-1 and data3==-1):
                    mistakes=mistakes+1
                if (mistakes>5):
                    print "base address %08X doesn't look correct"%(readAddress)
		    break;
                if ((data0==0x1F or data0==0x1E or data0==0x1C or data0==0x1A or data0==0x10 ) and data1==0x00 and data2==0x00 and data3==0x00):
                    print "!!!!!!!!!!!!!!!!!!!!!!!!!!!candidate!!!!!!!!!!!!!!!!!"
                    candidateAddress=readAddress+i*4
    		    break;  # nevertheless will continue scanning

if (candidateAddress<=0 and 1==1):
    print ">Scanning memory"
    for randomAddressBase in (0x60000000,0xC2000000,0xC8000000,-1):
        for randomAddressOffset in (0x00000000,0x00000100,-1):
            if (randomAddressBase>=0 and randomAddressOffset>=0):
                readAddress=randomAddressBase+randomAddressOffset
                readAddress0=readAddress/(256*256*256)
                readAddress1=(readAddress-readAddress0*256*256*256)/(256*256)
                readAddress2=(readAddress-readAddress0*256*256*256-readAddress1*256*256)/(256)
                readAddress3=(readAddress-readAddress0*256*256*256-readAddress1*256*256-readAddress2*256)/(1)
                print "Read Memory at %08X=%02X %02X %02X %02X"%(readAddress,readAddress0,readAddress1,readAddress2,readAddress3)
                sendFrame(ser,encodeHeaderCKFrame([0x10,iCommand,DS_MSG_MEMORY_PROTECTED+DS_MSG_MEMORY_SEGMENTED,readSize, 0x00, readAddress0,readAddress1,readAddress2,readAddress3 ,0x00,0x00, ProcessIDh,ProcessIDl ,0x00,0x00, ThreadIDh,ThreadIDl,-1]))  # Read Memory
                s = ser.read(400)	# Read Memory get
                myBytes=showFrameBin(s)
                if (debug>2): print myBytes
                iCommand=iCommand+1
                if (myBytes[2]==0x20): # kDSReplyOsError
                    print "The OS reported an error :-("
                else:
                    mistakes=0
                    for i in range(0,readSize*256/4):
                        data0=myBytes[5+i*4+0]
                        data1=myBytes[5+i*4+1]
                        data2=myBytes[5+i*4+2]
                        data3=myBytes[5+i*4+3]
                        print "Read Memory %08X=%02X %02X %02X %02X"%(readAddress+i*4,data0,data1,data2,data3)
                        if (i<=7 and data0==-1 and data1==-1 and data2==-1 and data3==-1):
                            mistakes=mistakes+1
                        if (mistakes>5):
                            print "base address %08X doesn't look correct"%(readAddress)
                            break;
                        if ((data0==0x1F or data0==0x1E or data0==0x1C or data0==0x1A or data0==0x10 ) and data1==0x00 and data2==0x00 and data3==0x00):
                            print "!!!!!!!!!!!!!!!!!!!!!!!!!!!candidate!!!!!!!!!!!!!!!!!"
                            candidateAddress=readAddress+i*4
                            break;  # nevertheless will continue scanning
    
if (candidateAddress>0):
    print ">Write Memory %08X"%(candidateAddress)
    writeAddress=candidateAddress
    writeAddress0=writeAddress/(256*256*256)
    writeAddress1=(writeAddress-writeAddress0*256*256*256)/(256*256)
    writeAddress2=(writeAddress-writeAddress0*256*256*256-writeAddress1*256*256)/(256)
    writeAddress3=(writeAddress-writeAddress0*256*256*256-writeAddress1*256*256-writeAddress2*256)/(1)
    print "write Memory at %08X=%02X %02X %02X %02X"%(writeAddress,writeAddress0,writeAddress1,writeAddress2,writeAddress3)
    writeSize=0x4
    dataWrite0=0x10
    sendFrame(ser,encodeHeaderCKFrame([0x11,iCommand,0x08,0x00,writeSize,writeAddress0,writeAddress1,writeAddress2,writeAddress3,0x00,0x00,ProcessIDh,ProcessIDl,0x00,0x00,ThreadIDh,ThreadIDl,dataWrite0,0x00,0x00,0x00,-1]))  # write Memory
    s = ser.read(400)	# Write Memory get
    myBytes=showFrameBin(s)
    if (debug>2): print myBytes
    iCommand=iCommand+1

print ">Stop"
sendFrame(ser,encodeHeaderCKFrame([0x1A,iCommand,0x02,0x00,0x00,ProcessIDh,ProcessIDl,0x00,0x00,ThreadIDh,ThreadIDl,-1]))  # Stop
s = ser.read(1400)	# Stop get + Notify Stopped ... should extract messageID and ack it
myBytes=showFrameBin(s)
if (debug>2): print myBytes
iCommand=iCommand+1

print ">Ack Notify Stopped"
sendFrame(ser,encodeHeaderCKFrame([0x80,0x02,0x00,-1]))  # Ack Notify Stopped
s = ser.read(40)	# There is no answer, but clean buffer
# myBytes=showFrameBin(s)
# print myBytes
# iCommand=iCommand+1

print ">Disconnect"
sendFrame(ser,encodeHeaderCKFrame([0x02,iCommand,-1]))	# Disconnect
s = ser.read(40)	# Disconnect get
myBytes=showFrameBin(s)
if (debug>2): print myBytes
iCommand=iCommand+1

print ">Close"
ser.close()
print ">End+Exit"

