/// <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); }
/// <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); }
/// <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; } }
/// <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(); }
/// <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); }