-2

I am gathering binary information from a multicast stream on a VERY old system. I have converted most of it, but I am having problems with a High / Low DWORD Combo. I wrote a little test app to try to iron this out. I am being told the value should be in the 30XXX range.

The documentation I was given says it is defined as ...

DWORD ID_HIGH;
DWORD ID_LOW;

I am just getting garbage so far. I have tried bit shifts and a bunch of other routes. So far, no luck. Any assistance is appreciated.

static void Main(string[] args)
        {            
            byte[] data = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x51};

            Int32 ID_High = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0));
            Int32 ID_Low = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));
            Int64ToInt32 i6;
            i6.Int64Value = 0;
            i6.LeftInt32 = ID_High;
            i6.RightInt32 = ID_Low;


        }

        [StructLayout(LayoutKind.Explicit)]
        struct Int64ToInt32
        {
            [FieldOffset(0)]
            public Int64 Int64Value;
            [FieldOffset(0)]
            public Int32 LeftInt32;
            [FieldOffset(4)]
            public Int32 RightInt32;
        }

For More information. Here is the entire byte[] received from the Multicast.

byte[] data = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x51, 0x00, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x50, 0x00, 0x00, 0x04, 0x7F,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x90, 0x3E, 0xE4, 0x62, 0xB8, 0xB1, 0x4D, 0xB0, 0xF1, 0x15, 0x94,
                            0xF1, 0x13, 0x0F, 0x84, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };

And here is the definition of what it is supposed to translate to.

typedef struct
{
    DWORD AgentID_High; // Agent phoneset login ID high-order 32 bits
    DWORD AgentID_Low; // Agent phoneset login ID low-order 32 bits
    DWORD State;
    DWORD SupervisorID_High; // Supervisor phoneset login ID high-order 32 bits
    DWORD SupervisorID_Low; // Supervisor phoneset login ID low-order 32 bits
    DWORD TimeInState;
    DWORD AnsweringSkillset;
    DWORD DNInTimeInState;
    DWORD DNOutTimeInState;
    BYTE SupervisorUserID[16];
    DWORD PositionID;
    // TM26314
    DWORD NotReadyReasonCode_High;
    DWORD NotReadyReasonCode_Low;
    DWORD DNOutCallNumber_High;
    DWORD DNOutCallNumber_Low;
    DWORD SkillsetCallAnswered;
    DWORD DNInCallAnswered;
    DWORD DNOutCallMade;
    //Q00635846 griffinn MIROS Changes
    DWORD AnsweringApplication;
    DWORD AnsweringCDN_High;
    DWORD AnsweringCDN_Low;
    DWORD AnsweringDNIS_High;
    DWORD AnsweringDNIS_Low;
} NIMultiCastAgentRecord_Rls5; // size = 104 bytes

All the other DWORDS parse fine with just IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0)); Except these split words. I personally thought the data didn't seem right but I wanted second opinions.

**Latest Development.. The agent ID is 30451 from what I am being told. if you look at the hex bits it is right there in the HEX.

byte[] data = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x51};

So here is what I came up with. I feel like I am breaking all kinds of rules here...

string AgentID = BitConverter.ToString(data);
AgentID = AgentID.Replace("-", "").Replace("F", "");
vSteve
  • 63
  • 1
  • 1
  • 8
  • In network order, as a signed 32-bit integer, `ff` `f3` `04` `51` would be -850863, and the four preceding `ff` values are just sign extension to 64 bits. That's nowhere near 30 thousand (assuming that's what 30XXX means). – madreflection Oct 16 '19 at 23:21
  • Also, `i6.LeftInt32` should be assigned from `ID_Low`, the low bits from taken from [4] through [7]. – madreflection Oct 16 '19 at 23:23
  • `IPAddress` has a method overload that takes a 64-bit value. Try IPAddress.NetworkToHostOrder(BitConverter.ToInt64(data, 0))` . Once your data matches your expectations, that should take care of it without the explicit-layout struct. – madreflection Oct 16 '19 at 23:45
  • 1
    There's not enough information here to tell you what's wrong. But, the data you provided doesn't look like any number in the range of 30000 to 30999, or even 0x30000 to 0x30fff. Even if we take the smallest byte and make that the most significant one, that gives us a number larger than 67,000,000. If you could say what _exactly_ those bytes are supposed to represent, it would be trivial to figure out how they are encoded. Without that information, all anyone can do is guess. – Peter Duniho Oct 17 '19 at 00:03
  • Added a bit more info, hopefully this helps. I agree the data doesn't look right for these at all. I didn't think it should start with 4x 0xFF. Its been awhile since I dealt with this kind of stuff so I am seeking other opinions. – vSteve Oct 17 '19 at 00:48
  • FWIW, your post shows that `data.Length == 105` but you also say that `sizeof(NIMultiCastAgentRecord_Rls5) == 104` - so something else is amiss. – Dai Oct 17 '19 at 01:04
  • \0 to end the array makes it 105 vs the data of 104. – vSteve Oct 17 '19 at 04:09
  • - madreflection : I had the bits swaped (left and right) and also tried the Int64. Neither worked. – vSteve Oct 17 '19 at 17:00

1 Answers1

-1

You say it's a value in the range "30XXX" - so 30,000 to 30,999.

Decimal    Hex big-endian    Hex little-endian
30000           0x75 0x30            0x30 0x75
30999           0x79 0x17            0x17 0x79

So in any event, we're looking for at least a single byte in the range 0x75 to 0x79 which will exist regardless of whether it's a 16-bit, 32-bit, or 64-bit-sized integer, and also regardless of if it's big-endian or little-endian.

None of the bytes you've posted are in that range - therefore it's impossible for any of those values to represent a value in the range 30,000 to 30,999 using normal integers.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • If I flip the bits I get a number in the right range. (Bitwise NOT) But why would I have to do this? – vSteve Oct 17 '19 at 04:16
  • @Steve: _"If I flip the bits I get a number in the right range"_ -- how do you figure that? Interpreting your data as signed, it represents `-850863` (2's complement). Negating that gives you 850863. If you view the bits as 1's complement instead and just flip the bits, the result is 850862. Neither of those values are anywhere close to 30000 (decimal). Are you saying that the "range" you describe is hexadecimal? If so, it sure would be a lot better if you'd make that clear in your question. – Peter Duniho Oct 17 '19 at 04:43
  • I should stop answering at 1am.. I am just reaching to find some reasoning here. So what I did is this... FF FF FF FF | FF F3 04 51 -> 1111 1111 x4 | 1111 1111 1111 0011 0000 0100 0101 0001 -> 0000 0000 | 0000 0000 0000 1100 1111 1011 1010 1110 = 850,862 Then read it backwards 0111 0101 1101 1111 = 30,175.. But that ignores the last 0011, which I didn't notice last night. Pure chance I guess. Just frustrated because they swear there isn't a problem with their data. I verified my byte[] with Wireshark as well and it consistently outputs the same stuff. – vSteve Oct 17 '19 at 12:30
  • @vSteve so the data is bitwise `NOT` *and* bitwise-flipped? Wat? (so for example, given `0x59`, `NOT( 0x59 ) == ( 0xA6 == 1010 0110b )` then reverse the order of the bits in the byte to `0110 0101 == 0x65`. That's crazy. – Dai Oct 17 '19 at 12:45
  • yes, yes it is. This really all comes down to a simple question. Am I missing a step when parsing these things or is the data FUBAR. – vSteve Oct 17 '19 at 13:01
  • @vSteve If by "multicast" you mean IP multicast over UDP, then it's certainly unconventional (and beware of packet loss with UDP - you can't do multicast with TCP) and I'd be annoyed too - but if you're reading from something else, like an RS-232 serial data line or other low-level hardware then I wouldn't know because embedded applications/systems often have their own (very reasonable!) reasons for doing things the way they're doing, e.g. "Active-Low" in electronics - which makes no sense to a software engineer :P ) – Dai Oct 17 '19 at 13:10
  • I am using multicast over UDP.. Definitely not by choice. – vSteve Oct 17 '19 at 17:02