Convert byte array to string with a checksum. Getting additional null bytes on re-iteration in python

StackOverflow https://stackoverflow.com/questions/20379284

Question

Ok here's my question. Actually two.

I am getting additional null bytes when running my code after the first pass, what am I doing wrong?

2nd question, how do I form the packet from the byte array and with the added checksum?

I have a bytearray that I need to do an XOR on to get a checksum value. The starting checksum has to be 5A before the XOR. This needs to be appended to the end of the array and sent to my external device.

I 'THINK' I am doing this right, but I am not getting a response from the device. I have checked the device and it is working correctly, so I am assuming it is my code.

So with that I have put up the code below. Any help forming the packet to send out would be very helpful as I have been knocking my head against the wall. I am not a very experienced python programmer but I can usually figure things out when they are explained or examples given.

import struct
import sys
import string
import select
import time
from socket import *
import binascii


port = 8010
# region Read Codes
getBoardTemp = [0x02, 0x53, 0x00, 0x00]
#Communication utilities

class CommUtilities:
    def unhex(self, inp):
        return binascii.unhexlify(inp)

    def hexit(self, inp):
        return binascii.a2b_hex(inp)

    def calculateChecksum(self, buf):
        checksum = 0x5A #Starting checksum
        #For each byte, bitwise XOR it with our checksum
        for b in buf:
            checksum ^= b
        print 'Checksum: {}'.format(checksum)
        return checksum

    #Append the one byte checksum to a command
    #returns the complete byte array
    def appendChecksum(self, buff):
        buff.append(self.calculateChecksum(buff))
        return buff


def send_server(data, host):
        sock=socket(AF_INET,SOCK_STREAM)
        sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sock.setblocking(0)
        sock.settimeout(3)
        sock.connect((host, 1000))
        sock.sendall(data)
        print 'Sent Data'
        print 'Waiting for return data'
        result = sock.recv(1024)

        sock.close()
        return result


def main():
    c = CommUtilities()
    host = "172.16.2.52"
    while True:
        try:
            #Connect to server and send data
            print 'Requesting Board Temp'
            data = c.appendChecksum(getBoardTemp)
            """ The checksum should have appended a 0B byte into the array
            """
            data = bytearray(data)
            print data
            print'sending "%s"' % data
            """  The sending "%s" is where I noticed extra nulls being appedned
            on each pass.  They accumulate as the application keeps running.
            """
            received = send_server(data, host)
            """ I have yet to receive any return data, other than the ACK
            packets from the device.  So I am assuming my data I am sending is wrong.
            """
        except Exception, e:
            print >>sys.stderr, 'send/receive error {}'.format(e)
            received = e
        finally:
            print "received: {}".format(received)

        time.sleep(2)

if __name__ == '__main__':
    main()

I thank you in advance for you help!

Was it helpful?

Solution

The problem is CommUtilities.appendChecksum() modifies the contents of its buff argument (and after the first iteration, the checksum it calculates is zero). You can fix that with by simply making a copy first:

    def appendChecksum(self, buff):
        buff = buff[:]  # make copy
        buff.append(self.calculateChecksum(buff))
        return buff

I'm not sure, but that may also answer your second question.

OTHER TIPS

appendChecksum always append one byte to the input parameter, getBoardTemp in your code. I don't understand why you say "The checksum should have appended a 0B byte into the array".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top