Ejemplo n.º 1
0
        // метода се извиква при всяко запитване на конектнатия клиент
        public byte[] ProccessRequest(byte[] message)
        {
            //извличане на входните данни
            var splittedMessage = SplitByteArray(message, 0x1F).ToArray();

            if (splittedMessage.Count() == 0)
            {
                return new byte[] { 0x45, 0x52, 0x52, 0x4F, 0x52 }
            }
            ;                                                       //ERROR

            // how many tokens
            int tokensCount = splittedMessage.GetLength(0);
            // command
            string cmd = tokensCount >= 1 ? new string(
                splittedMessage[0]
                .Where(b => b != 0x1F && b != 0x1E)     // except:  0x1F - unit separator char(31), 0x1E - record separator char(30)
                .Select(b => (char)b)
                .ToArray()) : string.Empty;

            if (cmd.Equals("RG", StringComparison.InvariantCultureIgnoreCase))
            {
                CanPlayRequest request = CanPlayRequest.DeserializeASCII(splittedMessage);

                _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(request));
                Proto.CanPlayRequest proto_request = request.ToProtoCanPlayRequest();
                CanPlayResponse      response;
                try
                {
                    Proto.CanPlayResponse proto_response = _cardService.CanPlayAsync(proto_request).Result;
                    if (proto_response != null)
                    {
                        response = CanPlayResponse.FromProtoCanPlayResponse(proto_response);
                    }
                    else
                    {
                        response = new CanPlayResponse {
                            Success = false, MessageLine1 = "Err 109", MessageLine2 = "Internal server"
                        };
                        _logger.LogError("TextMessageService.ProccessRequest => Proto.CanPlayResponse is null");
                    }
                }
                catch (Exception ex)
                {
                    response = new CanPlayResponse {
                        Success = false, MessageLine1 = "Err 109", MessageLine2 = "Internal server"
                    };
                    _logger.LogError($"TextMessageService.ProccessRequest throws: {ex}");
                }
                _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(response));
                return(response.SerializeASCII());
            }
            else if (cmd.Equals("RP", StringComparison.InvariantCultureIgnoreCase))
            {
                ServicePriceRequest request = ServicePriceRequest.DeserializeASCII(splittedMessage);
                _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(request));
                Proto.ServicePriceRequest proto_request = request.ToProtoServicePriceRequest();
                ServicePriceResponse      response;
                try
                {
                    Proto.ServicePriceResponse proto_response = _cardService.ServicePriceAsync(proto_request).Result;
                    if (proto_response != null)
                    {
                        response = ServicePriceResponse.FromProtoServicePriceResponse(proto_response);
                    }
                    else
                    {
                        response = new ServicePriceResponse {
                            Success = false, MessageLine1 = "Err 109", MessageLine2 = "Internal server"
                        };
                        _logger.LogError("TextMessageService.ProccessRequest => Proto.ServicePriceRequest is null");
                    }
                }
                catch (Exception ex)
                {
                    response = new ServicePriceResponse {
                        Success = false, MessageLine1 = "Err 109", MessageLine2 = "Internal server"
                    };
                    _logger.LogError($"TextMessageService.ProccessRequest throws: {ex}");
                }
                _logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(response));
                return(response.SerializeASCII());
            }
            else if (cmd.Equals("T", StringComparison.InvariantCultureIgnoreCase))
            {
                return(Encoding.ASCII.GetBytes($"{DateTime.Now:dd.MM.yyyy HH:mm}\x1E"));
            }
            else
            {
                return(Encoding.ASCII.GetBytes($"{DateTime.Now:dd.MM.yyyy HH:mm}\x1E"));
            }
        }
Ejemplo n.º 2
0
        private void OnHoldingRegistersChanged(UInt16 register, UInt16 numberOfHoldingRegisters)
        {
            Int16[] resultBuffer;

            int           gRPCId = -1;      //число, идентификатор на извикваната процедура
            string        concentratorId;   //4 UTF16 символа, ляво допълнени с '0'
            string        controllerId;     //8 UTF16 символа, ляво допълнени с '0'
            string        cardType;         //2 UTF16 символа, ляво допълнени с '0'
            string        cardId;           //16 UTF16 символа, ляво допълнени с '0'
            int           endpointRssi;     //число от 0 до 255
            int           concentratorRssi; //число от 0 до 255
            StringBuilder sb = new StringBuilder();

            /************************************************************************
             * 1. извличане на данните от HoldingRegisters
             *************************************************************************/
            #region 1

            // 1.0 идентификатор на извикваната процедура. определя се от ранга на адреса на 1-вия регистър (40001-49999; 0x9C41-0xC34F)

            //Can play
            if (register == 40001)
            {
                gRPCId = 1;                         //40001(0x9C41); 128 регистъра x16
            }
            else if (register == 40127)
            {
                gRPCId = 2;                         //40001(0x9C41) + 128(0x0080) - 2 = 40127(0x9CBF); 128 регистъра x16
            }
            else if (register == 40255)
            {
                gRPCId = 3;                         //40001(0x9C41) + 256(0x0100) - 2 = 40255(0x9D3F); 128 регистъра x16
            }
            else if (register == 40383)
            {
                gRPCId = 4;                         //40001(0x9C41) + 384(0x0180) - 2 = 40383(0x9DBF); 128 регистъра x16
            }
            // 1.1 идентификатор на концентратора - 4 регистъра x16
            for (UInt16 i = 0; i <= 3; i++)
            {
                sb.Append(Convert.ToChar(
                              _modbusSlave.HoldingRegisters[(UInt16)(register + i)]));
            }
            #region OLD
            //sb.Append(
            //    Encoding.UTF8.GetString(
            //        BitConverter.GetBytes(
            //            _modbusSlave.HoldingRegisters[(UInt16)(register + i)])));
            #endregion
            concentratorId = sb.ToString();
            sb.Clear();
            // 1.2 идентификатор на контролера - 8 регистъра x16
            for (UInt16 i = 4; i <= 11; i++)
            {
                sb.Append(Convert.ToChar(
                              _modbusSlave.HoldingRegisters[(UInt16)(register + i)]));
            }
            controllerId = sb.ToString();
            sb.Clear();
            // 1.3 тип на картата - 1 регистър x16
            cardType = Convert.ToChar(
                _modbusSlave.HoldingRegisters[(UInt16)(register + 12)]).ToString();
            // 1.4 идентификатор на картата - 16 регистъра x16
            for (UInt16 i = 14; i <= 29; i++)
            {
                sb.Append(Convert.ToChar(
                              _modbusSlave.HoldingRegisters[(UInt16)(register + i)]));
            }
            cardId = sb.ToString();
            sb.Clear();
            // 1.5 endpointRssi и concentratorRssi - Hi byte и Lo byte в последния регистър x16
            byte[] b2 = BitConverter.GetBytes(
                _modbusSlave.HoldingRegisters[(UInt16)(register + numberOfHoldingRegisters - 1)]);
            endpointRssi     = b2[0]; //Hi byte
            concentratorRssi = b2[1]; //Lo byte

            #endregion

            /************************************************************************
             * 2. анализ и обработка на данните, извикване на gRPC процедурите и получаване на резултата от тях
             *************************************************************************/
            #region 2

            //Can play
            if (gRPCId == 1)
            {
                resultBuffer = new Int16[numberOfHoldingRegisters + 20]; // !!! Да се увеличи с толкова колкото са необходими за CanPlayResponse
                Proto.CanPlayResponse response;

                if (_cardService == null)
                {
                    response = new Proto.CanPlayResponse();
                    {
                        response.Time           = DateTime.Now;
                        response.TransactionId  = 1; // get as parameter
                        response.ConcentratorId = concentratorId;
                        response.ControllerId   = controllerId;
                        response.CardType       = cardType.Length > 1 ? int.Parse(cardType.TrimStart('0')) : int.Parse(cardType);
                        response.CardId         = cardId;
                        response.CardNumber     = string.Empty;
                        response.Permission     = false;
                        response.DisplayLine1   = "ERROR";
                        response.DisplayLine2   = "Service unavailable";
                    };
                }
                else
                {
                    var request = new Proto.CanPlayRequest();
                    request.Time             = DateTime.Now;
                    request.TransactionId    = 1;// get as parameter
                    request.ConcentratorId   = concentratorId;
                    request.ControllerId     = controllerId;
                    request.CardType         = cardType.Length > 1 ? int.Parse(cardType.TrimStart('0')) : int.Parse(cardType);
                    request.CardId           = cardId;
                    request.ShouldPay        = false;
                    request.EndpointRssi     = endpointRssi;
                    request.ConcentratorRssi = concentratorRssi;
                    response = _cardService.CanPlayAsync(request).Result;
                }
                // Fill resultBuffer from CanPlayResponse
                int ix = 0;
                // 2.1 идентификатор на концентратора - 4 регистъра x16
                foreach (char c in response.ConcentratorId.PadLeft(4, '0'))
                {
                    resultBuffer[ix] = Convert.ToInt16(c);
                    ix++;
                }
                // 2.2 идентификатор на контролера - 8 регистъра x16
                foreach (char c in response.ControllerId.PadLeft(8, '0'))
                {
                    resultBuffer[ix] = Convert.ToInt16(c);
                    ix++;
                }
                // 2.3 тип на картата - 1 регистър x16
                if (response.CardType <= 9)
                {
                    resultBuffer[ix] = Convert.ToInt16(Convert.ToChar(response.CardType));
                }
                else
                {
                    resultBuffer[ix] = (short)0;
                }
                ix++;
                // 2.4 идентификатор на картата - 16 регистъра x16
                foreach (char c in response.CardId.PadLeft(16, '0'))
                {
                    resultBuffer[ix] = Convert.ToInt16(c);
                    ix++;
                }
                // 2.5 резултат - 1 регистър x16
                resultBuffer[ix] = response.Permission ? (short)1 : (short)0;
            }
            else
            {
                resultBuffer = new Int16[numberOfHoldingRegisters];
            }

            #endregion

            /************************************************************************
             * 3. прехвърляне на резултатните данни в InputRegisters
             *************************************************************************/
            #region 3
            UInt16 firstInputRegister = 30001;                  //30001-39999
            if (gRPCId == 1)
            {
                firstInputRegister = 30001;                     //30001(0x7531); 2048 регистъра x16
            }
            else if (gRPCId == 2)
            {
                firstInputRegister = 32047;                     //30001(0x7531) + 2048(0x0800) - 2 = 32047(0x7D2F); 2048 регистъра x16
            }
            else if (gRPCId == 3)
            {
                firstInputRegister = 34095;                     //30001(0x7531) + 4096(0x1000) - 2 = 34095(0X852F); 2048 регистъра x16
            }
            else if (gRPCId == 4)
            {
                firstInputRegister = 36143;                     //30001(0x7531) + 6144(0x1800) - 2 = 36143(0x8D2F); 2048 регистъра x16
            }
            for (var i = 0; i < resultBuffer.Length; i++)
            {
                _modbusSlave.InputRegisters[unchecked ((UInt16)(firstInputRegister + i))] = resultBuffer[i];
            }

            #endregion

            /************************************************************************
             * 4. нулиране на HoldingRegisters
             *************************************************************************/
            #region 4

            _modbusSlave.ClearHoldingRegisters();

            #endregion
        }