this is totally unrelated...but ive been searching help on p/invoke
for HAI_NetLib and your name came up Fred, im just wondering if you
ever figured out how to replicate R_OMNI_LINK_MESSAGE in .NET
thanks
The R_OMNI_LINK_MESSAGE works in .net, the problem is a syntax difference
between C++ and C#. Not being a C# programmer I don't know the exact
changes that must be made. I was looking at it this morning and found
some examples of structure and union declarations in C#.
If you are an experienced C# programmer you could probably do this faster
than me.
This is how I developed the structure in the first place:
All Omni Messages are of the format:
Start character (1 byte)
Message length (1 byte)
Message type (1 byte)
Data (Zero or more bytes, depending on the specific "message type")
CRC 1 (1 byte)
CRC 2 (1 byte)
Basically, for backward compatibility, we are wrapping the serial packet
inside a net packet. For this reason the CRC can be ignored, and besides
I have already verified the CRC in my dll. If you get the packet it is
OK.
Likewise the start character is always the same and can also be ignored.
For your purposes the "useful" data begins with the length byte. And
looks like this:
Message length (1 byte)
Message type (1 byte)
Data (Zero or more bytes, depending on the specific "message type")
This is what my dll returns, and this is the basic record structure.
Since structure the "Data" portion can vary depending on "type" I created
a union of all of the currently known record types where the "Data"
portion of the record exists. It so happens that there are no duplicate
element/field names so naming the sub structures was not necessary and
simplifies things a bit.
I also defined a generic "unsigned char Data[255];" union so you could
also refer the the various parts of the "Data" block as Data[n], like in
the documentation.
You may notice that a few substructures are missing. This is because
messages like "logout" have no data.
Here is a fragment to see if I can meke it clearer:
struct R_OMNI_LINK_MESSAGE {
unsigned char MessageLength;
union {
unsigned char Data[255];
struct {
unsigned char MessageType;
union {
struct /* olmNAME_DATA (8 bit) */ {
unsigned char ItemType8;
unsigned char ItemNumber8;
unsigned char ItemName8[16];
};
struct /* olmNAME_DATA (16 bit) */ {
unsigned char ItemType16;
unsigned char ItemNumber16MSB;
unsigned char ItemNumber16LSB;
unsigned char ItemName16[16];
};
}; // union
}; // struct
}; // union
};
Look at the structure and try to think in terms of columns:
First there's "unsigned char MessageLength;" which begins in column 0.
Then there is a union that means that the array "Data" and the rest of
the structure, BOTH begin in column 1. This means that Data[0] and
MessageType are both located at the same location, column 1.
This is really the only oddity in the structure. You might wonder why I
put Data in union with Message type, and not where the data actually
begins in column 2. Well I didn't really like it, but throughout the
documentation all references to data begin with data 1. Since all arrays
in C start at subscript 0, I shifted the array to start one byte earlier,
so "Data[x]" would match up with "Data x" in the existing documentation.
Remember we have 10's of thousands of customers and need to maintain that
backward compatibility.
The next 2 structures BOTH begin in column 2.
Also watch those "unsigned char Something[16]" strings. I don't think
they are compatible with the ByValTStr type in C#?
Hopefully you can see the pattern. It gets a little tricky in a few of
these sub structures, because some of them are arrays of sub-sub-
structures. If you break it down it really isn't that bad.
If you really don't like the complex looking structure then don't use it.
You can always define the 30 or 40 individual record structures then use
a case statement based on the record type to decide which record
structure to use. Or as some users do, and did before the structure was
created, pick the record apart byte by byte. The documentation brakes it
down for each record like this:
Start character 0x5A
Message length 0x1E
Message type 0x12 (SYSTEM INFORMATION)
Data 1 model number
Data 2 major version
Data 3 minor version
Data 4 revision
Data 5-29 local phone number
CRC 1 varies
CRC 2 varies
Finally do you have the latest API kit? I provided a VC++ .NET example a
while back, but I think it never made it to the web site because we were
overhauling it. You may have noticed that the new site went up last
night. Go to the site and get the latest documentation and examples. It
may help.
Well that's more than I intended to say...