prob with struct and byte order

nephish at xit.net nephish at xit.net
Tue Jul 25 10:11:33 EDT 2006


ok. here is how i got a message in the first place. The data server
developers released this one windows app that simulates a real app. In
that it logs into the server and sends and receives commands. instead
of putting in the data servers ip though, i put in the ip address of
the linux box i am building this on. when a command got sent, i had a
listening socket open that would receive the command from the
simulation program and dump it into a mysql table. So far its worked
becuase the same command works with the real server. But now, i have to
learn how to contruct messages for real because of the control we want
to have over the field units.

i put this in

def split_message(message):
    if not (message.startswith('STX') or message.endswith('ENX')):
        raise ValueError('missing start or end sequence')
    length, message_type = struct.unpack('>II', message[3:11])
    return length, message_type, message[11:-3]

print 'length: %d\ntype: %d\n%r' % split_message(data)

and this is what was in the txt file. ( i am using a text file for
sys.stdout becuase my terminal app does not do copy and paste.)

length: 52
type: 200
'stateman\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00stat1manet\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

i used the same snippit for a query message
length: 44
type: 234
'1758466855\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd6\t\rT\x00\x00\x00\x00'

now, the message type 234 is correct according to the docs. Here is
what it has to say.
query_ANSI:
used to request information about a particular data system in the field
unsigned long int     messageType = 234;
unsigned char          primaryMIN(32);  # this is the serial number of
the unit
unsigned long int     ESN # serial number of the communicator
unsigned long int     userID


thanks again guys.. i think we're getting closer.

-sk

John Machin wrote:
> Marc 'BlackJack' Rintsch wrote:
> > In <1153785622.870353.85960 at b28g2000cwb.googlegroups.com>, nephish wrote:
> >
> > > tohex gave me
> > > '53 54 58
> >
> >    S  T  X
> >
> > > 00 00 00 34
> >
> > Length!?  Decimal 57.
>
> 3 * 16 + 4 -> 52 where I come from -- assuming hex means hexadecimal
> and not witchcraft :-)
>
> >
> > > 00 00 00 c8
> >
> > Type!?  Decimal 200.
> >
> > > 70 69 76 6f 74 72 61 63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > 74 72 61 63 31 70 69 76 6f 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >
> > Payload!?
> >
> > > 45 4e 58'
> >
> >   E  N  X
> >
> > > this is the login message (message type 200)
> >
> >
> > The problem I see is the length.  The payload without STX, ENX and the two
> > numbers in front is 47 bytes so there's a 5 byte difference.
>
> I don't think so.
>
> >  You have to
> >  look at some more messages to get an idea how the length corresponds to
> >  the actual payloads length.
>
> Yes, but not because of the 5-difference problem. The OP has favoured
> us with 3 messages (in 3 different formats), 2 x login and 1 of some
> sort of data. See below.
>
> 8<--- script start
> import struct
>
> def unhex(s, spaced):
>     return ''.join([chr(int(s[x:x+2], 16)) for x in xrange(0, len(s), 2
> + spaced)]) # gasp
>
> hex1 =
> "5354580000002c000000ea3137353834363638353500000000000000000000000000000000000000000000d6090d5400000000454e58"
> txt1 = unhex(hex1, 0)
>
> txt2 =
> 'STX\x00\x00\x004\x00\x00\x00\xc8stateman\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00state1man\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ENX'
>
>
> hex3 = '53 54 58 00 00 00 34 00 00 00 c8 70 69 76 6f 74 72 61 63 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 74 72 61 63 31 70 69 76 6f 74
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 45 4e 58'
> txt3 = unhex(hex3, 1)
>
> for msgno, msg in enumerate((txt1, txt2, txt3)):
>     print "\nMessage %d: length of actual string is %d" % (msgno + 1,
> len(msg))
>     print "Has STX/ENX:", msg.startswith("STX") and msg.endswith("ENX")
>     print "repr:", repr(msg)
>     print "hex :", ' '.join(["%02x" % ord(x) for x in msg])
>     msg_len, msg_type = struct.unpack('>II', msg[3:11])
>     print "Internal len: %d; type: %d" % (msg_len, msg_type)
> 8<--- end script, start output
>
> Message 1: length of actual string is 54
> Has STX/ENX: True
> repr:
> 'STX\x00\x00\x00,\x00\x00\x00\xea1758466855\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd6\t\rT\x00\x00\x00\x00ENX'
> hex : 53 54 58 00 00 00 2c 00 00 00 ea 31 37 35 38 34 36 36 38 35 35 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d6 09 0d
> 54 00 00 00 00 45 4e 58
> Internal len: 44; type: 234
>
> Message 2: length of actual string is 61
> Has STX/ENX: True
> repr:
> 'STX\x00\x00\x004\x00\x00\x00\xc8stateman\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00state1man\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ENX'
> hex : 53 54 58 00 00 00 34 00 00 00 c8 73 74 61 74 65 6d 61 6e 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 73 74 61 74 65 31 6d 61 6e 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 45 4e 58
> Internal len: 52; type: 200
>
> Message 3: length of actual string is 62
> Has STX/ENX: True
> repr:
> 'STX\x00\x00\x004\x00\x00\x00\xc8pivotrac\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00trac1pivot\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ENX'
> hex : 53 54 58 00 00 00 34 00 00 00 c8 70 69 76 6f 74 72 61 63 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 74 72 61 63 31 70 69 76 6f 74 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 45 4e 58
> Internal len: 52; type: 200
> 8<---
> Messages 1 and 3 tend to indicate that external_len == internal_len +
> 10 ... maybe there's been a copy/paste problem somewhere along the line
> with message 2; perhaps the OP could check this.
> 
> Cheers,
> John




More information about the Python-list mailing list