コード例 #1
0
ファイル: KPUtils.cs プロジェクト: AMM-VSU/scada-mono
        /// <summary>
        /// Считать данные из последовательного порта
        /// </summary>
        /// <param name="serialPort">Последовательный порт</param>
        /// <param name="buffer">Буфер принимаемых данных</param>
        /// <param name="index">Начальный индекс в буфере</param>
        /// <param name="maxCount">Максимальное количество принимаемых байт</param>
        /// <param name="stopCode">Байт, означающий окончание считывания данных</param>
        /// <param name="timeout">Таймаут чтения данных, мс</param>
        /// <param name="wait">Ожидать завершения таймаута после окончания чтения</param>
        /// <param name="logText">Строка для вывода в журнал</param>
        /// <returns>Количество считанных байт</returns>
        public static int ReadFromSerialPort(SerialPort serialPort, byte[] buffer, int index, int maxCount,
                                             byte stopCode, int timeout, bool wait, out string logText)
        {
            int readCnt = 0;

            if (serialPort == null)
            {
                logText = KPUtils.ReadDataImpossible;
            }
            else
            {
                DateTime nowDT   = DateTime.Now;
                DateTime startDT = nowDT;
                DateTime stopDT  = startDT.AddMilliseconds(timeout);

                bool stop   = false;
                int  curInd = index;
                serialPort.ReadTimeout = 0;

                while (readCnt <= maxCount && !stop && startDT <= nowDT && nowDT <= stopDT)
                {
                    bool readOk;
                    try { readOk = serialPort.Read(buffer, curInd, 1) > 0; }
                    catch { readOk = false; }

                    if (readOk)
                    {
                        stop = buffer[curInd] == stopCode;
                        curInd++;
                        readCnt++;
                    }
                    else
                    {
                        Thread.Sleep(100); // накопление входных данных в буфере порта
                    }

                    nowDT = DateTime.Now;
                }

                logText = ReceiveNotation + " (" + readCnt + "): " + KPUtils.BytesToHex(buffer, index, readCnt);

                if (wait && startDT <= nowDT)
                {
                    int delay = (int)(stopDT - nowDT).TotalMilliseconds;
                    if (delay > 0)
                    {
                        Thread.Sleep(delay);
                    }
                }
            }

            return(readCnt);
        }
コード例 #2
0
ファイル: KPUtils.cs プロジェクト: AMM-VSU/scada-mono
        /// <summary>
        /// Считать данные из последовательного порта
        /// </summary>
        /// <param name="serialPort">Последовательный порт</param>
        /// <param name="buffer">Буфер принимаемых данных</param>
        /// <param name="index">Начальный индекс в буфере</param>
        /// <param name="count">Количество принимаемых байт</param>
        /// <param name="timeout">Таймаут чтения данных, мс</param>
        /// <param name="wait">Ожидать завершения таймаута после окончания чтения</param>
        /// <param name="logText">Строка для вывода в журнал</param>
        /// <returns>Количество считанных байт</returns>
        public static int ReadFromSerialPort(SerialPort serialPort, byte[] buffer, int index, int count,
                                             int timeout, bool wait, out string logText)
        {
            int readCnt = 0;

            if (serialPort == null)
            {
                logText = ReadDataImpossible;
            }
            else
            {
                // данный способ чтения данных необходим для избежания исключения
                // System.ObjectDisposedException при прерывании потока линии связи
                DateTime nowDT   = DateTime.Now;
                DateTime startDT = nowDT;
                DateTime stopDT  = startDT.AddMilliseconds(timeout);
                serialPort.ReadTimeout = 0;

                while (readCnt < count && startDT <= nowDT && nowDT <= stopDT)
                {
                    try { readCnt += serialPort.Read(buffer, index + readCnt, count - readCnt); }
                    catch { /*The operation has timed out*/ }

                    if (readCnt < count)
                    {
                        Thread.Sleep(100); // накопление входных данных в буфере порта
                    }
                    nowDT = DateTime.Now;
                }

                logText = ReceiveNotation + " (" + readCnt + "/" + count + "): " +
                          KPUtils.BytesToHex(buffer, index, readCnt);

                if (wait && startDT <= nowDT)
                {
                    int delay = (int)(stopDT - nowDT).TotalMilliseconds;
                    if (delay > 0)
                    {
                        Thread.Sleep(delay);
                    }
                }
            }

            return(readCnt);
        }
コード例 #3
0
ファイル: KPUtils.cs プロジェクト: AMM-VSU/scada-mono
 /// <summary>
 /// Записать данные в последовательный порт
 /// </summary>
 /// <param name="serialPort">Последовательный порт</param>
 /// <param name="buffer">Буфер передаваемых данных</param>
 /// <param name="index">Начальный индекс в буфере</param>
 /// <param name="count">Количество передаваемых байт</param>
 /// <param name="logText">Строка для вывода в журнал</param>
 public static void WriteToSerialPort(SerialPort serialPort, byte[] buffer, int index, int count, out string logText)
 {
     try
     {
         if (serialPort == null)
         {
             logText = WriteDataImpossible;
         }
         else
         {
             serialPort.DiscardInBuffer();
             serialPort.DiscardOutBuffer();
             serialPort.Write(buffer, index, count);
             logText = SendNotation + " (" + count + "): " + KPUtils.BytesToHex(buffer, index, count);
         }
     }
     catch (Exception ex)
     {
         logText = (Localization.UseRussian ?
                    "Ошибка при отправке данных: " : "Error sending data: ") + ex.Message;
     }
 }
コード例 #4
0
ファイル: KpSmsLogic.cs プロジェクト: southasia/scada
        /// <summary>
        /// Отправить команду ТУ
        /// </summary>
        public override void SendCmd(Command cmd)
        {
            base.SendCmd(cmd);
            lastCommSucc = false;

            if (cmd.CmdType == CmdType.Binary && (cmd.CmdNum == 1 || cmd.CmdNum == 2))
            {
                string logText; // текст для вывода в log-файл линии связи
                string cmdData = new string(Encoding.Default.GetChars(cmd.CmdData));
                if (cmdData.Length > 0)
                {
                    if (cmd.CmdNum == 1)
                    {
                        // отправка сообщения
                        // данные команды: <телефон>;<текст>
                        // телефонный номер указывается только для основного КП на линии связи
                        int    scPos = cmdData.IndexOf(';');
                        string phone = primary ? (scPos > 0 ? cmdData.Substring(0, scPos).Trim() : "") : CallNum;
                        string text  = scPos < 0 ? cmdData : scPos + 1 < cmdData.Length ?
                                       cmdData.Substring(scPos + 1).Trim() : "";

                        if (phone == "" || text == "")
                        {
                            WriteToLog(Localization.UseRussian ?
                                       "Отсутствует телефонный номер или текст сообщения" :
                                       "No telephone number or message text");
                        }
                        else
                        {
                            int    pduLen;
                            string pdu = MakePDU(phone, text, out pduLen);

                            KPUtils.WriteLineToSerialPort(SerialPort, "AT+CMGS=" + pduLen, out logText);
                            WriteToLog(logText);
                            Thread.Sleep(100);

                            try
                            {
                                if (SerialPort != null)
                                {
                                    SerialPort.NewLine = "\x1A";
                                }
                                KPUtils.WriteLineToSerialPort(SerialPort, pdu, out logText);
                                WriteToLog(logText);
                            }
                            finally
                            {
                                if (SerialPort != null)
                                {
                                    SerialPort.NewLine = "\x0D";
                                }
                            }

                            List <string> inData = KPUtils.ReadLinesFromSerialPort(SerialPort, KPReqParams.Timeout,
                                                                                   false, "OK", out lastCommSucc, out logText);
                            WriteToLog(logText);

                            Thread.Sleep(KPReqParams.Delay);
                        }
                    }
                    else
                    {
                        // произвольная AT-команда
                        KPUtils.WriteLineToSerialPort(SerialPort, cmdData, out logText);
                        WriteToLog(logText);

                        List <string> inData = KPUtils.ReadLinesFromSerialPort(SerialPort, KPReqParams.Timeout,
                                                                               false, new string[] { "OK", "ERROR" }, out lastCommSucc, out logText);
                        WriteToLog(logText);

                        Thread.Sleep(KPReqParams.Delay);
                    }
                }
                else
                {
                    WriteToLog(Localization.UseRussian ? "Отсутствуют данные команды" : "No command data");
                }
            }
            else
            {
                WriteToLog(Localization.UseRussian ? "Недопустимая команда" : "Illegal command");
            }

            CalcCmdStats();
        }
コード例 #5
0
ファイル: KpSmsLogic.cs プロジェクト: southasia/scada
        /// <summary>
        /// Сеанс опроса основного КП
        /// </summary>
        private void PrimarySession()
        {
            string logText; // текст для вывода в log-файл линии связи
            int    i;

            // отключение эхо
            if (WorkState != WorkStates.Normal)
            {
                lastCommSucc = false;
                i            = 0;
                while (i < CommLineParams.TriesCnt && !lastCommSucc && !Terminated)
                {
                    WriteToLog(Localization.UseRussian ? "Отключение эхо" : "Set echo off");
                    KPUtils.WriteLineToSerialPort(SerialPort, "ATE0", out logText);
                    WriteToLog(logText);

                    KPUtils.ReadLinesFromSerialPort(SerialPort, KPReqParams.Timeout,
                                                    false, "OK", out lastCommSucc, out logText);
                    WriteToLog(logText);

                    FinishRequest();
                    i++;
                }
            }

            // сброс вызова
            if (lastCommSucc)
            {
                lastCommSucc = false;
                i            = 0;
                while (i < CommLineParams.TriesCnt && !lastCommSucc && !Terminated)
                {
                    WriteToLog(Localization.UseRussian ? "Сброс вызова" : "Drop call");
                    KPUtils.WriteLineToSerialPort(SerialPort, "ATH" /*"AT+CHUP"*/, out logText);
                    WriteToLog(logText);

                    List <string> inData = KPUtils.ReadLinesFromSerialPort(SerialPort, KPReqParams.Timeout,
                                                                           false, "OK", out lastCommSucc, out logText);
                    WriteToLog(logText);

                    FinishRequest();
                    i++;
                }
            }

            // обработка и удаление сообщений, полученных ранее
            int eventCnt = 0; // количество созданных событий

            if (lastCommSucc)
            {
                foreach (Message msg in messageList)
                {
                    // обработка сообщения, если оно не обработано другими КП
                    try
                    {
                        object[] msgObjArr = msg.Reference;
                        if (!(bool)msgObjArr[5] /*сообщение не обработано*/ &&
                            (int)msgObjArr[1] <= 1 /*принятое сообщение*/)
                        {
                            // запись события
                            WriteEvent(msg.TimeStamp, msg.Phone, msg.Text, ref eventCnt);
                            msgObjArr[5] = true;
                        }
                    }
                    catch
                    {
                        WriteToLog((Localization.UseRussian ? "Ошибка при обработке сообщения " :
                                    "Error processing message ") + msg.Index);
                    }

                    // удаление сообщений из памяти GSM-терминала
                    bool deleteComplete = false;
                    i = 0;
                    while (i < CommLineParams.TriesCnt && !deleteComplete && !Terminated)
                    {
                        WriteToLog((Localization.UseRussian ? "Удаление сообщения " : "Delete message ") + msg.Index);
                        KPUtils.WriteLineToSerialPort(SerialPort, "AT+CMGD=" + msg.Index, out logText);
                        WriteToLog(logText);

                        KPUtils.ReadLinesFromSerialPort(SerialPort, KPReqParams.Timeout,
                                                        false, "OK", out deleteComplete, out logText);
                        WriteToLog(logText);

                        FinishRequest();
                        i++;
                    }
                    lastCommSucc = lastCommSucc && deleteComplete;
                }

                messageList.Clear();
                GetMessageObjList().Clear();
            }

            IncEventCount(eventCnt);
            if (lastCommSucc)
            {
                WriteToLog((Localization.UseRussian ? "Количество полученных сообщений: " :
                            "Received message count: ") + eventCnt);
            }

            // запрос списка сообщений
            if (lastCommSucc)
            {
                lastCommSucc = false;
                i            = 0;

                while (i < CommLineParams.TriesCnt && !lastCommSucc && !Terminated)
                {
                    WriteToLog(Localization.UseRussian ? "Запрос списка сообщений" : "Request message list");
                    KPUtils.WriteLineToSerialPort(SerialPort, "AT+CMGL=4", out logText);
                    WriteToLog(logText);

                    List <string> inData = KPUtils.ReadLinesFromSerialPort(SerialPort, KPReqParams.Timeout,
                                                                           false, "OK", out lastCommSucc, out logText);
                    WriteToLog(logText);

                    // расшифровка сообщений
                    if (lastCommSucc)
                    {
                        string errMsg;
                        if (!FillMessageList(inData, out errMsg))
                        {
                            WriteToLog(errMsg);
                            lastCommSucc = false;
                        }
                    }

                    FinishRequest();
                    i++;
                }

                // запись сообщений в общие свойства линии связи
                List <object[]> msgObjList = GetMessageObjList();
                foreach (Message msg in messageList)
                {
                    object[] msgObjArr = ConvertMessage(msg);
                    msg.Reference = msgObjArr;
                    msgObjList.Add(msgObjArr);
                }
            }

            // определение наличия связи
            double newVal = lastCommSucc ? 1.0 : -1.0;

            SetParamData(0, newVal, 1);
        }