Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ar"></param>
        private void NetworkReadBuffer(IAsyncResult ar)
        {
            int bytesRead = Stream.EndRead(ar);

            try
            {
                // read PDU data from stream
                ProtocolDataUnit pdu = ProtocolDataUnit.ReadFrom(tempBuffer);
#if TRACE
                if (pdu != null)
                {
                    Messages.Trace("[SNIP .. Packet Rx from " + PhysicalAddress.ToString() + "]");
                    Messages.TraceHex("hdr", pdu.HeaderData, pdu.HeaderData.Length);
                    Messages.Trace("hdr->checksum = " + pdu.Header.CRC.ToString("X"));
                    Messages.Trace("hdr->length = " + pdu.Header.Length.ToString());
                    Messages.Trace("hdr->macAddr = " +
                                   pdu.Header.MacAddr[0].ToString("X") + ":" +
                                   pdu.Header.MacAddr[1].ToString("X") + ":" +
                                   pdu.Header.MacAddr[2].ToString("X") + ":" +
                                   pdu.Header.MacAddr[3].ToString("X") + ":" +
                                   pdu.Header.MacAddr[4].ToString("X") + ":" +
                                   pdu.Header.MacAddr[5].ToString("X"));
                    Messages.Trace("hdr->dataLength = " + pdu.Header.DataLength);
                    Messages.Trace("hdr->compressLength = " + pdu.Header.CompressedLength);
                    Messages.Trace("hdr length " + pdu.Header.Length);
                    if (pdu.ContentData != null)
                    {
                        Messages.TraceHex("frame", pdu.ContentData, pdu.ContentData.Length);
                        Messages.Trace("frame length " + pdu.ContentData.Length);
                        Messages.Trace("MAC Destination = " +
                                       pdu.ContentData[0].ToString("X") + ":" +
                                       pdu.ContentData[1].ToString("X") + ":" +
                                       pdu.ContentData[2].ToString("X") + ":" +
                                       pdu.ContentData[3].ToString("X") + ":" +
                                       pdu.ContentData[4].ToString("X") + ":" +
                                       pdu.ContentData[5].ToString("X"));
                        Messages.Trace("MAC Source = " +
                                       pdu.ContentData[6].ToString("X") + ":" +
                                       pdu.ContentData[7].ToString("X") + ":" +
                                       pdu.ContentData[8].ToString("X") + ":" +
                                       pdu.ContentData[9].ToString("X") + ":" +
                                       pdu.ContentData[10].ToString("X") + ":" +
                                       pdu.ContentData[11].ToString("X"));
                    }
                    Messages.Trace("[SNIP .. Packet Rx from " + PhysicalAddress.ToString() + "]");
                }
#endif

                // reset exception counter
                if (streamExceptionCount > 0)
                {
                    streamExceptionCount = 0;
                }

                // did we receive a pdu?
                if (pdu != null)
                {
                    // are we trying to shut down the session?
                    if ((pdu.Header.CRC == 250) && (pdu.Header.DataLength == 65535))
                    {
                        Close();
                        return;
                    }

                    // are we trying to register a client?
                    if ((pdu.Header.CRC == 255) && (pdu.Header.DataLength == 0))
                    {
                        HandshakeHeader header = new HandshakeHeader();
                        header.CRC              = 255;
                        header.DataLength       = 0;
                        header.CompressedLength = 0;
                        header.Length           = (ushort)header.Size;

                        byte[] node = new byte[6];

                        // generate a new MAC address
                        // set first 3 octets
                        node[0] = 0xAC;
                        node[1] = 0xDE;
                        node[2] = 0x48;

                        // maybe this is a reconnect? we have the last 3 of an assigned MAC
                        if ((pdu.Header.MacAddr[3] != 0) && (pdu.Header.MacAddr[4] != 0) && (pdu.Header.MacAddr[5] != 0))
                        {
                            Messages.WriteWarning("session reconnect? we recieved the last 3 " +
                                                  pdu.Header.MacAddr[3].ToString("X") + ":" +
                                                  pdu.Header.MacAddr[4].ToString("X") + ":" +
                                                  pdu.Header.MacAddr[5].ToString("X"));
                            node[3] = pdu.Header.MacAddr[3];
                            node[4] = pdu.Header.MacAddr[4];
                            node[5] = pdu.Header.MacAddr[5];
                        }
                        else
                        {
                            Random rand = new Random();
                            node[3] = (byte)rand.Next(255);
                            node[4] = (byte)rand.Next(255);
                            node[5] = (byte)rand.Next(255);
                        }

                        header.MacAddr  = node;
                        this.macAddress = node;

                        Messages.Trace("new session macAddr = " +
                                       macAddress[0].ToString("X") + ":" +
                                       macAddress[1].ToString("X") + ":" +
                                       macAddress[2].ToString("X") + ":" +
                                       macAddress[3].ToString("X") + ":" +
                                       macAddress[4].ToString("X") + ":" +
                                       macAddress[5].ToString("X"));

                        // build final payload
                        byte[] buffer = new byte[Util.RoundUp(header.Size, 4)];
                        header.WriteTo(buffer, 0);

                        // transmit
                        if (Stream.CanWrite)
                        {
                            Stream.Flush();
                            Stream.Write(buffer, 0, buffer.Length);
                            Stream.Flush();
                        }
                        return;
                    }

                    commMgr.BroadcastPacket(pdu);
                }
            }
            catch (IOException)
            {
                waitMRE.Wait(1); // wait a bit before reading again
                waitMRE.Set();

                // increment exception counter
                streamExceptionCount++;
                if (streamExceptionCount >= MAX_STREAM_EXECPTIONS)
                {
                    this.Close();
                }
            }
            finally
            {
                waitMRE.Set();
            }
        }