allowing message strings to contain zero bytes

Project:SOCKIT - speaking and listening to TCP/IP network sockets using IGOR Pro
Version:IGOR.5.00.x-1.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:andyfaff
Status:closed
Description

While trying to communicate with an LeCroy oscilloscope (Waverunner 6100A) using the SOCKIT xop, I stumbled on another problem. The operations SOCKITsendmsg and SOCKITsendnrecv don't seem to handle message strings containing zero bytes (0x00).
The commands sent to the oscilloscope must be preceeded with an 8 byte header (as it is described on page 34 of the LeCroy Remote Control Manual) that contains also 0x00 bytes.
In my example the easiest command is *idn? (in hex: 2A 69 64 6E 3F) which makes the oscilloscope identify itself and the header is (in hex): 81 01 01 00 00 00 00 05, but only the first three bytes (81 01 01) are sent. I verified this using a network monitor tool and I tested both the mac and the win xop.
Would it be a great effort to implement this functionality?

Updates

#1 submitted by andyfaff on September 9, 2008 - 03:24

Hmm,
SOCKIT was designed to send ASCII strings, as I'm not sure how to create binary data in IGOR (I'll think about it). However, we may be able to get somewhere with this.
Can you try using num2char(0) wherever you need to use 0x00. This works because the ASCII character with decimal value 0, is 00 in Hex. Simply append strings like normal.
For a list of ASCII codes and their corresponding HEX values see:

  • http://www.ascii-code.com/
  • #2 submitted by andyfaff on September 9, 2008 - 03:26

    I was just thinking, a byte normally has 8 bits. 8 bits = 2^8 =256. Therefore you should be able to use num2char to describe all those binary values (0 to 255 = 256 values).

    #3 submitted by awirsing on September 9, 2008 - 06:09
    Attachment:grab0.png (80.96 KB)

    I used to build the message string like:

    •string msg
    •msg=num2char(129)+num2char(1)+num2char(1)+num2char(0)+num2char(0)+num2char(0)+num2char(0)+num2char(5)+"*idn?"

    and used msg as the argument for SOCKITsendmsg:

    •SOCKITsendmsg socketID, msg
    SOCKITmsg: wrote to socket 56
    Å

    Now I tried to write the zero bytes directly to the message argument of SOCKITsendmsg:

    sockitsendmsg socketID, num2char(129)+num2char(1)+num2char(1)+num2char(0)+num2char(0)+ num2char(0)+num2char(0)+num2char(5)+"*idn?"

    This was - as I expected - also unsuccessful as again only the first three bytes of the header were sent to the instrument.
    It is not an issue of Igor, because Igor knows how long the string is:

    •print strlen(msg)
    13

    You can also address single characters of the string:

    •print msg[0],char2num(msg[5]),msg[8],msg[8,12]
    Å 0 * *idn?

    #4 submitted by andyfaff on September 9, 2008 - 07:22

    I think I've discovered what the problem is. I have fixed the correct sending of the message, on my computer. However, I have to fix the reception of those types of messages.
    I've been determining how long each message is by using strlen. This is wrong in this case, as strlen stops when it sees \0 (0x00).

    #5 submitted by awirsing on September 9, 2008 - 10:38

    I should mention that also the answer of the oszilloscope is preceeded by that 8 byte header...

    #6 submitted by andyfaff on September 9, 2008 - 17:52
    Attachment:SOCKIT.xop_.zip (184.71 KB)

    Can you try this version, to see it it works. It should send and receive what is required, but won't print out to screen properly at the moment.

    #7 submitted by andyfaff on September 10, 2008 - 01:52

    I've done more mods, the zip version that I sent this morning wouldn't have outputted the data correctly.
    Try out the latest download version it should hopefully do what we need.

    Some points:
    1) S_tcp may not contain the full incoming message, as the C code that creates it is based on a Cstrings, which are terminated by NUL. Therefore if you use sockitsendnrecv then S_tcp will probably only contain the message up to a NUL terminator.
    2) I always add a NUL terminator to S_tcp before I output it. This is so the XOPtoolkit function from WM doesn't fall over if I try to output a Cstring that isn't NUL terminated.
    3) Given points 1+2 I would rely on the information contained in the bufferwave which should be exactly the same as the received message.

    I would really like to know how you get on (spent 4 hours on it all today). I would like to put out details on this site how to connect to these oscilloscopes if you manage to get it working.

    #8 submitted by andyfaff on September 10, 2008 - 01:54
    Category:feature request» bug report
    Assigned to:awirsing» andyfaff
    Status:active» patch (code needs review)
    #9 submitted by awirsing on September 10, 2008 - 05:39

    I just tried the new version of the xop.
    SOCKITsendnrecv works now, but has the limitations you mentioned regarding S_tcp. I copied a few lines of the history for illustration:

    •make/o/t/n=0 bufferwave; string msg
    •msg=num2char(129)+num2char(1)+num2char(1)+num2char(0)+num2char(0)+num2char(0)+num2char(0)+num2char(5)+"*idn?"
    •sockitopenconnection/q socketID,"172.25.1.2",1861,bufferwave; sockitsendnrecv/SMAL socketID, msg; sockitcloseconnection(socketID)
    •msg=bufferwave[1][0]; make/o/n=(strlen(msg))/t tw=msg[p]; print strlen(S_tcp); print tw; print msg[8,47]
    3
    tw[0]= {"Å","","","","","","",")","*","I","D","N"," ","L","E","C","R","O","Y",",","W","R","6","1","0","0","A",",","L","C","R","Y","0","6","0","4","P","1","5","0","6","3",",","5",".","1",".","1","\n"}
    *IDN LECROY,WR6100A,LCRY0604P15063,5.1.1

    When I use SOCKITsendmsg, I get no response from the instrument, the bufferwave is not even redimensioned, although the oscilloscope receives the query and sends the response (I can intercept the response with a network sniffer tool). I am also able to change the settings of the oscilloscope.

    I agree that communicating with modern lab instruments - not only LeCroy scopes - (which widely use TCP/IP) using your SOCKIT xop is probably of huge interest for many Igor Pro users, because it allows them on the one hand to control these instruments and on the other hand it should also be possible to read out data from these instruments. This requests of course some new functionalities to be added to your xop. To read out binary data one can for example think a new opreation that requests an single precision wave (or an integer wave) instead of the bufferwave in addition to a pointer variable pointing to the first data point in the received message. The data could so be written directly to an Igor binary wave. This is actually a topic for a new feature request.

    What the LeCroy oscilloscope concerns (you asked for that):
    The message string is composed of the 8 byte header and the actual command.
    An overview of the commands is given in part 2 of the LeCroy Remote Control Manual.
    The header structure is described on page 34. I figured it out empirically by intercepting messages sent to the scope from LabView:
    The first byte has a bit-wise meaning (see page 35), but as I found only the first and the last bit is set which leads to an integer value of 129 or 0x81. The second byte defines the header version (was in my case always 1 or 0x01). The meaning of the third byte is unclear to me, but I think it is arbitrary. The fourth byte is reserved for future expansion and is therefore 0 (0x00). Byte 5-8 define an int32 number wich descibes the (byte) length of the following command.

    #10 submitted by andyfaff on September 10, 2008 - 15:30

    I'm glad that we've got this far. However, I'm slightly disturbed that the message doesn't seem to be received properly when you use sockitsendmsg.

    Both sockitsendmsg and sockitsendnrecv use the same code which puts the received data into bufferwaves, so I'm mystified why one does it properly, but the other doesn't. I did notice that you used the /Q flag. When that is issued nothing is printed.

    Can you repeat the test you did in the last post using sockitsendmsg to double check, that the bufferwave isn't filled out? Sorry to ask this, but I can only debug with things like webservers which always return textual output.

    #11 submitted by andyfaff on September 10, 2008 - 16:36

    I've just modified the XOP again, for the sockitsendnrecv operation (read the help file for more info). Basically I've added an optional string parameter to the end of the operation. If you specify the string (which is either local or an SVAR) then the output is placed into it. This should handle the binary data properly. S_tcp is also created, but may not be perfectly correct.

    #12 submitted by awirsing on September 11, 2008 - 03:24

    I tried the SOCKITsendmsg again and found that it worked both with the old and the new version of the xop. I have no idea what I did wrong the last time I tested it...

    I don't know if it was so important to add the optional string, because the same information is already in the bufferwave (also the NUL bytes) and one cell of the bufferwave can be treated as string. See here for a raw example how such a binary read out could look like. This describes also another way of turning consecutive characters of a binary string into integers.

    #13 submitted by andyfaff on September 11, 2008 - 05:39

    I'm currently hard at work writing an extra operation that will convert string binary form to a wave. This should help transferring images, etc.

    #14 submitted by andyfaff on September 23, 2008 - 16:10
    Status:patch (code needs review)» fixed
    #15 submitted by Igor Pro User on October 7, 2008 - 16:45
    Status:fixed» closed

    Back to top