Пример #1
0
        /// <summary>
        /// HerzschlagRequest der Verbindung
        /// </summary>
        /// Sendet zyklich ein Telegramm an das Gateway dass die Verbindung noch aktiv ist
        internal void Heartbeat()
        {
            try
            {
                if (ConnectionState != KnxConnectionState.connected) // Upps, da stimmt was mit der Verbindung nicht
                {
                    HandleWrongConnectionState();
                }


                if (ConnectionState == KnxConnectionState.connected)
                {
                    KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this);
                    Tele.SetHeartbeatTelegramm();
                    byte[] TeleBytes = Tele.bytes;

                    // KnxNetForm
                    Debug("H>:" + KnxTools.BytesToString(TeleBytes));

                    udpClient.Send(TeleBytes, TeleBytes.Length);
                    ConnectionState = KnxConnectionState.hbReq;
                }
                else
                {
                    Err("Err: Heartbeat: State =" + ConnectionState.ToString());
                }
            }
            catch (Exception e)
            {
                Err("Err: Heartbeat: " + e.ToString());
            }
            return;
        }
Пример #2
0
        /// <summary>
        /// Schließen der Verbindung
        /// </summary>
        /// <returns>Rückgabewert true bedeutet die Verbindung konnte geschlossen werden</returns>
        public bool Close()
        {
            try
            {
                KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this);
                Tele.SetDisconnectTelegramm();
                byte[] TeleBytes = Tele.bytes;

                //KnxNetForm.tb_Log.AppendText(Environment.NewLine + "C>:" + KnxTools.BytesToString(TeleBytes));
                Debug("C>:" + KnxTools.BytesToString(TeleBytes));

                udpClient.Send(TeleBytes, TeleBytes.Length);
                ConnectionState = KnxConnectionState.disConReq;

                // Warten auf Antwort, maximal OpenTimeout Sekunden
                int i = 0;

                while ((i < 10 * OpenTimeout) & (ConnectionState != KnxConnectionState.disconnected))
                {
                    System.Threading.Thread.Sleep(100);
                    i++;
                }


                // Den Heartbeat Timer stoppen
                //timerHeartbeat.Stop();

                int        Anz = (int)ar.AsyncState;
                IPEndPoint e   = new IPEndPoint(IPAddress.Any, 0);
                try
                {
                    udpClient.EndReceive(ar, ref e);
                    udpClient.Close();
                }
                catch (InvalidOperationException ex)
                {
                }
                timerHeartbeat.Stop();
            }
            catch (Exception e)
            {
                Err("Close: " + e.ToString());
            }
            return(ConnectionState == KnxConnectionState.disconnected);
        }
Пример #3
0
        /// <summary>
        /// Daten auf den Bus senden
        /// </summary>
        /// <param name="emi">Telegrammdaten die gesendet werden sollen</param>
        public void Send(cEMI emi)
        {
            try
            {
                KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this);
                Tele.SetDataTelegramm(emi, SeqCounter++);
                byte[] TeleBytes = Tele.bytes;

                // KnxNetForm
                Debug("D>:" + KnxTools.BytesToString(TeleBytes));

                udpClient.Send(TeleBytes, TeleBytes.Length);
            }
            catch (Exception e)
            {
                Err("Send: " + e.ToString());
            }
            return;
        }
Пример #4
0
        internal void DataAck(byte seqNo)
        {
            try
            {
                KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this);
                Tele.SetDataAckTelegramm(seqNo);
                byte[] TeleBytes = Tele.bytes;

                // KnxNetForm
                Debug("d>:" + KnxTools.BytesToString(TeleBytes));

                udpClient.Send(TeleBytes, TeleBytes.Length);
            }
            catch (Exception e)
            {
                Err("DataAck: " + e.ToString());
            }
            return;
        }
Пример #5
0
        /// <summary>
        /// Öffnen der Verbindung
        /// </summary>
        /// <param name="gatewayIp"> IP Adresse des KnxIp-Gateways</param>
        /// <returns>Rückgabewert true bedeutet die Verbindung konnte geöffnet werden</returns>
        public bool Open(string gatewayIp)
        {
            this.gatewayIp = gatewayIp;
            //InitUdp();
            try
            {
                udpClient.Connect(gatewayIp, gatewayPort);
                myIP = ((IPEndPoint)udpClient.Client.LocalEndPoint).Address;

                KnxIpTelegrammGenerator Tele = new KnxIpTelegrammGenerator(this);
                Tele.SetConnectTelegramm();
                byte[] TeleBytes = Tele.bytes;

                //KnxNetForm.tb_Log.AppendText(Environment.NewLine + "O>:" + KnxTools.BytesToString(TeleBytes));
                Debug("O>:" + KnxTools.BytesToString(TeleBytes));

                udpClient.Send(TeleBytes, TeleBytes.Length);
                ConnectionState = KnxConnectionState.conReq;
            }
            catch (Exception e)
            {
                Err("Open: " + e.ToString());
            }

            // nun den Listener starten
            ar = udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), AnzTelegramme);

            // Warten auf Antwort, maximal OpenTimeout Sekunden
            int i = 0;

            while ((i < 10 * OpenTimeout) & (ConnectionState != KnxConnectionState.connected))
            {
                System.Threading.Thread.Sleep(100);
                i++;
            }

            // Den Heartbeat Timer starten
            timerHeartbeat.Start();

            return(ConnectionState == KnxConnectionState.connected);
        }
Пример #6
0
        /// <summary>
        /// Diese Funktion wird vom UDP-Client aufgerufen wenn ein neues Telegramm eingetroffen ist
        /// </summary>
        /// <param name="ar"></param>
        public void ReceiveCallback(IAsyncResult ar)
        {
            int        Anz = (int)ar.AsyncState;
            IPEndPoint e   = new IPEndPoint(IPAddress.Any, 0);

            Byte[] receiveBytes = udpClient.EndReceive(ar, ref e);
            Anz++;
            Debug("Empf: Telegr[" + Anz + "]=" + KnxTools.BytesToString(receiveBytes));
            int AnzBytes = receiveBytes.Length;

            if (AnzBytes < 7)
            {
                Err("Err: Telegramm zu kurz, wird verworfen. " + KnxTools.BytesToString(receiveBytes));
                return;
            }
            try
            {
                // prüfen ob es ein ControlTelegramm ist
                if (receiveBytes[2] == 0x02)
                {   // es ist ein Controlltelegramm
                    switch (receiveBytes[3])
                    {
                    case 0x01:      // Search Request
                        Debug("Search Request from Gateway");
                        Debug("<S:" + KnxTools.BytesToString(receiveBytes));
                        break;

                    case 0x02:      // Search Response
                        _channelId = receiveBytes[6];
                        Debug("Search Response from Gateway");
                        Debug("<s:" + KnxTools.BytesToString(receiveBytes));
                        break;

                    case 0x03:      // Description Request
                        Debug("Description Request from Gateway");
                        Debug("<D:" + KnxTools.BytesToString(receiveBytes));
                        break;

                    case 0x04:      // Description Response
                        _channelId = receiveBytes[6];
                        Debug("Description Response from Gateway");
                        Debug("<d:" + KnxTools.BytesToString(receiveBytes));
                        break;

                    case 0x05:      // Connect Request
                        Info("Connection Request from Gateway");
                        Debug("<O:" + KnxTools.BytesToString(receiveBytes));
                        break;

                    case 0x06:      // Connect Response
                        _channelId = receiveBytes[6];
                        Info("ChannelId = " + _channelId);
                        Debug("<o:" + KnxTools.BytesToString(receiveBytes));
                        if (receiveBytes[7] == 0)
                        {
                            ConnectionState = KnxConnectionState.connected;
                        }
                        break;

                    case 0x07:      // Heartbeat Request
                        Debug("HeartbeatRequest for ChannelId = " + _channelId);
                        Debug("<H:" + KnxTools.BytesToString(receiveBytes));
                        break;

                    case 0x08:      // Heartbeat Response
                        Debug("HeartbeatResponse from ChannelId = " + _channelId);
                        Debug("<h:" + KnxTools.BytesToString(receiveBytes));
                        if (receiveBytes[7] == 0)
                        {
                            ConnectionState = KnxConnectionState.connected;
                        }
                        break;

                    case 0x09:      // Disconnect Request
                        Debug("DisconnectRequest for ChannelId = " + _channelId);
                        Debug("<C:" + KnxTools.BytesToString(receiveBytes));
                        break;

                    case 0x0A:      // Disconnect Response
                        Debug("Disconnected ChannelId = " + _channelId);
                        Debug("<c:" + KnxTools.BytesToString(receiveBytes));
                        if (receiveBytes[7] == 0)
                        {
                            ConnectionState = KnxConnectionState.disconnected;
                        }
                        break;

                    default:
                        Debug("<?:" + KnxTools.BytesToString(receiveBytes));
                        break;
                    }
                }
                else if (receiveBytes[2] == 0x04)
                {     // es ist kein Controlltelegramm
                    if (receiveBytes[3] == 0x20)
                    { // es ist ein Datentelegramm
                        // erst ein Ack senden
                        DataAck(receiveBytes[8]);
                        // Header entfernen
                        int idx = 0x0A;
                        int len = receiveBytes.Length - idx;

                        byte[] t = new byte[len];
                        Array.Copy(receiveBytes, idx, t, 0, len);
                        // und cemi Telegramm daraus erzeugen
                        cEMI emi = new cEMI(t);
                        Debug("ReceiveCallback: " + emi.ToString());
                        // Suchen des passenden HDKnx Objektes
                        HDKnx hdKnx = HDKnxHandler.GetObject(emi);
                        // und dort den Wert setzen, falls erforderlich
                        hdKnx.SetValue(emi);
                        // und auch das emi übergeben
                        hdKnx.emi = emi;

                        // Prüfen auf doppelte Telegramme
                        if (hdKnx.Equals(last_hdKnx))
                        {   // verwerfen
                            //Info("doppeltes Telegramm verworfen:");
                        }
                        else
                        {
                            //Console.WriteLine("Setze last Telegramm: \r\nvon {0} == \r\nzu  {1}",last_hdKnx, hdKnx);

                            last_hdKnx = new HDKnx(hdKnx.emi);
                            // Rohdaten melden falls gewünscht
                            if (rawTelegramReceived != null)
                            {
                                rawTelegramReceived(t);
                            }

                            // geänderte Daten melden falls gewünscht
                            if (dataChanged != null)
                            {
                                Debug("KnxNet.ReceiveCallback vor dataChanged" + t.ToString());
                                dataChanged(hdKnx);
                                Debug("KnxNet.ReceiveCallback nach dataChanged" + t.ToString());
                            }

                            if (telegramReceived != null)
                            {   // Ein Delegate ist eingerichtet, dann diesen aufrufen
                                telegramReceived(emi);
                            }
                            if (QueueEnable)
                            {   // in Queue speichern
                                lock (fromKnxQueue)
                                {
                                    fromKnxQueue.Enqueue(emi);
                                }
                                Debug("AddToQueue: " + emi.ToString());
                            }
                        }
                    }
                    else if (receiveBytes[3] == 0x21)
                    {   // Bestätigung eines Datentelegramm
                        Debug("Daten bestätigt  status = " + receiveBytes[9]);
                    }
                }
                ar = udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), Anz);
            }
            catch (Exception ex)
            {
                Err("Err: Telegr[" + Anz + "]=" + KnxTools.BytesToString(receiveBytes));
                Err("Err: ReceiveCallback: " + ex.ToString());
                ar = udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), Anz);
            }
        }