Asterisk notifications (solved)

Discussions about using SIP Sorcery on your own computer/server
Nebukadnezar
Posts: 47
Joined: Tue Aug 10, 2010 1:46 pm

Re: Asterisk notifications (solved)

Post by Nebukadnezar » Fri Nov 05, 2010 9:06 am

My remark was meant in more general terms (though I did name .Net explicitly) and relates to my experiences with Microsoft overall. After spending weeks trying to get Vista working properly I reverted back to XP (and occasionally to w2k), which was not really a problem since I can boot those OS’s from the same machine (my hardware does not allow me (yet) to setup VMware like environments).

However, I must say that Window 7 really impresses me; no installation troubles and it ran immediately after the installation (no ‘funny’ stuff in the event logs and device manager). It required almost no tweaking and it actually runs faster than XP on the same hardware.

Currently, I hardly use previous versions anymore, and when I really feel like complaining I start one of my very old boxes and try to figure out how ‘ED’ worked again (CP/M on Z80).

Nebukadnezar
Posts: 47
Joined: Tue Aug 10, 2010 1:46 pm

Re: Asterisk notifications (solved)

Post by Nebukadnezar » Fri Nov 05, 2010 12:48 pm

Aaron,

I’m still working on the ICMP listener and puzzling how to deal with ‘endianness’. My first approach was getting the data out of the buffer into an array and then reversing the byte order, before passing the data on to the appropriate BitConverter. Though it works, it is not very elegant. Second approach was to prepare the buffer driven by a two dimensional array containing the position and length of fields that need to be adjusted. That works too, with an added advantage that existing code needs no changes, but it lacks in readability.

Table driven:

Code: Select all

        public static int[] pos = new int[] { 22, 48, 50 }; // Location of ushorts in network buffer
        public static int[] len = new int[] { 02, 02, 02 }; // length

        public static void Normalize(ref byte[] buffer)
        {
            if (BitConverter.IsLittleEndian)
            {
                for (int i = 0; i < pos.Length; i++)
                {
                    byte[] tmp = new byte[len[i]]; 
                    Buffer.BlockCopy(buffer, pos[i], tmp, 0, len[i]);
                    DequeueParse.ReverseBytes(tmp);
                    Buffer.BlockCopy(tmp, 0, buffer, pos[i], len[i]);
                }
            }
        }
Today I stumbled upon a Class, written by Pat Kujawa, that implements the BitConverter class, but takes ‘endianness’ in to account.

From your ICMP class:

Not working properly (on my Intel based system).

Code: Select all

        public ICMP(byte[] data, int size)
        {
            Type = data[20];
            Code = data[21];
            Checksum = BitConverter.ToUInt16(data, 22);
            MessageSize = size - 24;
            Buffer.BlockCopy(data, 24, Message, 0, MessageSize);
        }
Working properly.

Code: Select all

        public ICMP(byte[] data, int size)
        {
            Type = data[20];
            Code = data[21];
            Checksum = Utils.BitConverter.ToUInt16(data, 22);
            MessageSize = size - 24;
            Buffer.BlockCopy(data, 24, Message, 0, MessageSize);
        }
If you have a better method then I'm very interested.

User avatar
Aaron
Site Admin
Posts: 4563
Joined: Thu Jul 12, 2007 12:13 am

Re: Asterisk notifications (solved)

Post by Aaron » Fri Nov 05, 2010 10:39 pm

I'm suprised any BitConverter code from me is not working on your intel system as I've only ever developed on an intel system.

I also tend to use a converter class. You'll find the code below in the sipsorcery code base in the NetConvert class.

Code: Select all

public static UInt16 DoReverseEndian(UInt16 x) 
{
     return Convert.ToUInt16((x << 8 & 0xff00) | (x >> 8));
}
		
public static uint DoReverseEndian(uint x) 
{
    return (x << 24 | (x & 0xff00) << 8 | (x & 0xff0000) >> 8 | x >> 24);
}

public static ulong DoReverseEndian(ulong x)
{
    return (x << 56 | (x & 0xff00) << 40 | (x & 0xff0000) << 24 | (x & 0xff000000) << 8 | (x & 0xff00000000) >> 8 | (x & 0xff0000000000) >> 24 | (x & 0xff000000000000) >> 40 | x >> 56);
}

And then to use:

if (BitConverter.IsLittleEndian)
{
     SomeInt = NetConvert.DoReverseEndian(BitConverter.ToUInt32(packet, 0));
}

Nebukadnezar
Posts: 47
Joined: Tue Aug 10, 2010 1:46 pm

Re: Asterisk notifications (solved)

Post by Nebukadnezar » Sat Nov 06, 2010 9:00 am

I sincerely hope that you believe that no offence was meant. I am making an effort to understand the new programming environments available today, and I am very surprised that issues that existed way back in 1975 are still not appropriately dealt with. I had one of the first (ISA) network cards (targeted for Ethernet 1.0 and based on a Motorola 68020 CPU) developed for a (IBM) PC and I clearly remember the issues involved; not just multi word base types, but all data was in different ‘endiannnes’ (then 16 bit words), effectively killing the possibility to ‘DMA’ data.

I know that you do take ‘endianness’ in to account; SipSorcery would not work if you did not. No criticism is involved, just the need to understand and learn. Please consider the following piece of code:

Code: Select all

                                ICMP ICMPHeader = new ICMP(buffer, buffer.Length);
                                uint Type = (uint)ICMPHeader.Type;
                                uint Code = (uint)ICMPHeader.Code;
                                uint Checksum = ICMPHeader.Checksum;
All it does is instantiating an ICMP object given a buffer received. At this time ‘Checksum’ has been converted by the class ‘BitConverter’ and is based on the (standard) ‘little endianness’ of the (Intel based) PC. However, ‘Network order’ stipulates that the value of ‘Checksum’ is ‘big endian’ based.

That's all I meant. I did see your code dealing with this (in utilities.cs), but not in the specific case mentioned.

User avatar
Aaron
Site Admin
Posts: 4563
Joined: Thu Jul 12, 2007 12:13 am

Re: Asterisk notifications (solved)

Post by Aaron » Sat Nov 06, 2010 9:28 am

No offense taken, not even slightly, I wasn't aware that you'd even made a criticism :D.

I suspect you could very well be correct about the ICMP class I wrote missing something as far as endianess goes. I never really went very far with it as I didn't put in the time, as you have done, to work out how to set up a socket to receive them. And I see you point now if the checksum is big endian then it would need to be reversed for an intel system which I've failed to do.

Nebukadnezar
Posts: 47
Joined: Tue Aug 10, 2010 1:46 pm

Re: Asterisk notifications (solved)

Post by Nebukadnezar » Sat Nov 06, 2010 12:53 pm

One always has to be careful when quoting someone’s code; misunderstandings are easily born. I, (as one with a huge inferiority complex (and thus ‘probably’ right to think so), is always afraid to offend while trying to get a thought across.

As far as code goes, I’m trying to implement the thought of (and not in ANY way comparing myself to such a genius) Michelanchelo on sculptures:

‘the code I just wrote was there all the time, I just needed to cut away all the excess pieces.’

And on top of that; my command of the English language is as great as my command of the Latin language:

“Homo Sapiens non urinat in ventum” (it's not real Latin, but it is on top of a big gate here in Amsterdam(Max Euwe Plein, google it))

What would live be without humor?

(plees forchivve my Inglisj as I am dutch)

PS: I had a nice photo to go with the quote, bit I failed to get it inserted

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest