コード例 #1
0
 public string SendPipeMessage(CardOperationType cardType, string message, int timeout, bool canWrite = true)
 {
     using (NamedPipeClientStream stream = new NamedPipeClientStream("mrkpipe"))
     {
         stream.Connect(0x1388);
         stream.ReadMode = PipeTransmissionMode.Message;
         byte[] bytes = this._encoder.GetBytes(message);
         stream.Write(bytes, 0, bytes.Length);
         stream.Flush();
         this.WriteEntry(string.Format("{0} ++++++++++ PipeClient. Запрос: [{2}] ++++++++++ {0}{1}", Environment.NewLine, message, cardType), canWrite);
         Thread.Sleep(100);
         this._thread = new Thread(new ParameterizedThreadStart(this.ReadFunction));
         this._thread.Start(stream);
         string str  = string.Format("{0} ++++++++++ PipeClient. Ответ от МРК на запрос [{1}] ++++++++++ {0}", Environment.NewLine, cardType);
         bool   flag = false;
         if (!this._thread.Join(timeout))
         {
             flag = true;
             this._incommingMessage = string.Empty;
             stream.Close();
             this.Dispose();
         }
         if (this._incommingMessage == string.Empty)
         {
             str = str + (flag ? string.Format("MRK_TIME_OUT. PipeClient. МРК не ответил за отведенное время, прерываем поток чтения. Таймаут для этой операции {0} мс. ", timeout) : "MRK_NULL. PipeClient. Прочитана нулевая строка.");
             this.WriteEntry(str, canWrite);
             throw new WtfException("WTF");
         }
         this.WriteEntry(string.Format("{0}{1}", str, this._incommingMessage), canWrite);
         return(this._incommingMessage);
     }
 }
コード例 #2
0
 public OnCardChanged([NotNull] Card card, [NotNull] CardOperationType cardOperationType, string remark = null) : base()
 {
     AccountId         = card.AccountId;
     CardType          = card.CardType;
     CardNo            = card.CardNo;
     CardOperationType = cardOperationType.Key;
     Remark            = remark;
 }
コード例 #3
0
ファイル: ServioCardsShell.cs プロジェクト: mi1vus/PCSC_test
        public static int OperationSelector(CardOperationType type, IntPtr objRef, IntPtr serialNumber, IntPtr cardImage, IntPtr operation)
        {
            switch (type)
            {
            case CardOperationType.Credit:
                return(Credit(objRef, serialNumber, cardImage, operation));

            //case CardOperationType.Debit:
            //    return Debit(objRef, serialNumber, cardImage);
            case CardOperationType.Sale:
                return(Sale(objRef, serialNumber, cardImage, operation));

            //case CardOperationType.Refund:
            //    return Refund(objRef, serialNumber, cardImage/*, operation*/);
            case CardOperationType.Return:
                return(Return(objRef, serialNumber, cardImage, operation));

            default:
                return(-2000);
            }
        }
コード例 #4
0
ファイル: ServioCardsShell.cs プロジェクト: mi1vus/PCSC_test
        public static OpCode OperationSelector(CardOperationType type)
        {
            switch (type)
            {
            case CardOperationType.Credit:
                return(OpCode.OpCredit);

            case CardOperationType.Debit:
                return(OpCode.OpDebit);

            case CardOperationType.Sale:
                return(OpCode.OpDebit);

            case CardOperationType.Refund:
                return(OpCode.OpRefund);

            case CardOperationType.Return:
                return(OpCode.OpAnnulate);

            default:
                return(OpCode.OpAuthorization);
            }
        }
コード例 #5
0
 private void StartPooling(CardOperationType cardOperaionType)
 {
     //Thread _thread = new Thread(new ParameterizedThreadStart(this.WorkFunction));
     //_thread.Start(cardOperaionType);
     this.WorkFunction(cardOperaionType);
 }
コード例 #6
0
        private void WorkFunction(object poolingType)
        {
            lock (_lockObject)
            {
                AnsStatus status;
                decimal   maxBalance;
                string    str;
                object[]  objArray;
                decimal   num3;
                int       num = 0;
                this._cancel = false;
                do
                {
                    try
                    {
                        str        = new PipeClient().SendPipeMessage(CardOperationType.reqStatus, "<?xml version='1.0' encoding='windows-1251'?>\r\n<TCLib version='3.04'>\r\n\t<info>\r\n\t\t<reqStatus/>\r\n\t</info>\r\n</TCLib>", 0x1388, false);
                        status     = (AnsStatus)this.ExtractMessage(str, typeof(AnsStatus));
                        maxBalance = status.info.MrkStatus.MaxBalance;
                        //base.CallBack("LiveSignal", "");
                    }
                    catch (Exception exception1)
                    {
                        Exception exception = exception1;
                        Logger("ERROR! Pooling exception: " + exception.Message, EventEntryType.Error);
                        goto Label_05A4;
                    }
                    Thread.Sleep(0x3e8);
                    if (++num > 20)
                    {
                        Logger("20 секунд прошло, а карту так и не приложили для чтения. Высылаем МРК команду \"Cancel\"", EventEntryType.Event);
                        this.SendCancelCommand(true);
                        goto Label_05A4;
                    }
                }while (!status.info.MrkStatus.CardPresent);
                CardOperationType type = (CardOperationType)poolingType;
                string            arg  = (type == CardOperationType.Info) ? "Пожалуйста, подождите. Получаем выписку по карте..." : "this._readCardMessage";
                //base.CallBack("SetStartPooling", arg);
                //base.CallBack("LiveSignal", "");
                cardInfo cardInfo = null;
                string   str3     = string.Empty;
                string   str4     = string.Empty;
                try
                {
                    AnsWait    wait;
                    PipeClient client = new PipeClient();
                    client.Logger = Logger;
                    if (type == CardOperationType.Info)
                    {
                        str  = client.SendPipeMessage(CardOperationType.Info, string.Format("<?xml version='1.0' encoding='Windows-1251'?>\r\n<TCLib version='3.04'>\r\n\t<card>\r\n\t\t<reqWaitCard>\r\n\t\t\t<timeout>{0}</timeout>\r\n\t\t\t<application>1</application>\r\n\t\t\t<getInfo>2</getInfo>\r\n\t\t</reqWaitCard>\r\n\t</card>\r\n</TCLib>", "30"), 0x30d40, true);
                        wait = (AnsWait)this.ExtractMessage(str, typeof(AnsWait));
                        str4 = "this.CreateInfo(wait)";
                        //this.SetAccountInfo(wait.card.AnsWaitCard.CardInfo);
                    }
                    else
                    {
                        str      = client.SendPipeMessage(CardOperationType.reqWaitCard, string.Format("<?xml version='1.0' encoding='Windows-1251'?>\r\n<TCLib version='3.04'>\r\n\t<card>\r\n\t\t<reqWaitCard>\r\n\t\t\t<timeout>{0}</timeout>\r\n\t\t\t<application>1</application>\r\n\t\t\t<getInfo>1</getInfo>\r\n\t\t</reqWaitCard>\r\n\t</card>\r\n</TCLib>", "30"), 0x9c40, true);
                        wait     = (AnsWait)this.ExtractMessage(str, typeof(AnsWait));
                        cardInfo = wait.card.AnsWaitCard.CardInfo;
                        string[] strArray = cardInfo.Description.Split(new char[] { ',' });
                        string   str5     = (strArray.Length > 1) ? (", " + strArray[1]) : string.Empty;
                        this._maxValue = (maxBalance - cardInfo.Balance) / 100M;
                        objArray       = new object[4];
                        objArray[0]    = Environment.NewLine;
                        num3           = cardInfo.Balance / 100M;
                        objArray[1]    = num3.ToString("F").Replace(",", ".") + " руб." + str5;
                        objArray[2]    = cardInfo.Pan;
                        objArray[3]    = this.CreateDate(cardInfo.Date);
                        str3           = string.Format("Текущий баланс: {1}{0}Номер карты: {2}{0}Срок действия: {3}{0}", objArray) + ((this._maxValue > 0M) ? string.Format("Максимальная сумма пополнения: {0} руб.", this._maxValue) : "Карта пополнена на максимальную сумму");
                    }
                }
                catch (MrkErrorException exception2)
                {
                    string message = string.Format("Ошибка ожидания карты: {0}", exception2.Error.Description);
                    Logger(message, EventEntryType.Error);
                    if (exception2.Error.Code == 0x68)
                    {
                        this.SendCancelCommand(true);
                    }
                    else
                    {
                        //base.CallBack("SetCrashScreen", message);
                        Logger(string.Format("{0}: {1}", "SetCrashScreen", message), EventEntryType.Error);
                    }
                    goto Label_05A4;
                }
                catch (Exception exception4)
                {
                    //this.SetErrorScreen("Unexpected. Ошибка ожидания карты: " + exception4.ToString(), "Ошибка ожидания карты.", true);
                    Logger("Unexpected. Ошибка ожидания карты: " + exception4.ToString() + " Ошибка ожидания карты.", EventEntryType.Error);
                    goto Label_05A4;
                }
                switch (type)
                {
                case CardOperationType.reqWriteCard:
                    Logger("Пополнение. Дождались карту: " + Environment.NewLine + str3, EventEntryType.Event);
                    //this.SetAccountInfo(cardInfo);
                    //base.CallBack("SetWaitCardResult", str3);
                    Logger(String.Format("{0}; {1}", "SetWaitCardResult", str3), EventEntryType.Event);
                    if (this._maxValue > 0M)
                    {
                        //base.CallBack("SetButtonNext", "");
                    }
                    break;

                case CardOperationType.Balance:
                    Logger("Просмотр баланса. Дождались карту: " + str3, EventEntryType.Event);
                    //base.CallBack("SetBalanceResult", str3);
                    break;

                case CardOperationType.reqChangePin:
                    Logger("Смена пинкода. Дождались карту: " + str3, EventEntryType.Event);
                    //base.CallBack("StartChangePin", string.Empty);
                    break;

                case CardOperationType.reqPayment:
                    objArray    = new object[4];
                    objArray[0] = Environment.NewLine;
                    num3        = cardInfo.Balance / 100M;
                    objArray[1] = num3.ToString("F").Replace(",", ".");
                    objArray[2] = cardInfo.Pan;
                    objArray[3] = this.CreateDate(cardInfo.Date);
                    str3        = string.Format("Доступная для оплаты сумма: {1} руб.{0}Номер карты: {2}{0}Срок действия: {3}{0}", objArray);
                    Logger("Оплата по карте. Дождались карту: " + str3, EventEntryType.Event);
                    //base.CallBack("SetPan", cardInfo.Pan);
                    //base.CallBack("SetWaitCardResult", str3);
                    //base.CallBack("SetButtonNext", "");
                    break;

                case CardOperationType.Info:
                    //base.CallBack("SetDataGrid", str4);
                    break;
                }
                Label_05A4 :;
            }
        }
コード例 #7
0
        public DisppenserStatus SendAction(CardOperationType cardOperationType)
        {
            DisppenserStatus result = DisppenserStatus.DispenserError;
            PipeClient       client = new PipeClient();

            client.Logger = Logger;
            string      message   = client.SendPipeMessage(CardOperationType.reqStatus, reqStatus, PipeClient.CONNECT_TIMEOUT, true);
            AnsStatus   status    = (AnsStatus)this.ExtractMessage(message, typeof(AnsStatus));
            MrkStatuses mrkStatus = status.info.MrkStatus;

            if (!mrkStatus.MrkReady)
            {
                //this.SetErrorScreen("status.MrkReady == false", "МРК не готов к работе.", true);
                textLoger.Text += "МРК не готов к работе.";
            }
            else if (cardOperationType != CardOperationType.reqSaleCard)
            {
                if (mrkStatus.ReaderReady == 0)
                {
                    //base.CallBack("SetInfoWithMainMenu", this._readerErrorMessage);
                    Logger("Ошибка", EventEntryType.Error);
                }
                else
                {
                    client.SendPipeMessage(CardOperationType.reqControl_reader_1, "<?xml version='1.0' encoding='Windows-1251'?>\r\n<TCLib version='3.04'>\r\n\t<service>\r\n\t\t<reqControl>\r\n\t\t\t<reader>1</reader>\r\n\t\t</reqControl>\r\n\t</service>\r\n</TCLib>", PipeClient.CONNECT_TIMEOUT, true);
                    //base.CallBack("SetInfoWithMainMenu", this._waitCardMessage);
                    this.StartPooling(cardOperationType);
                    Logger("Ждем", EventEntryType.Event);
                }
            }
            else
            {
                DisppenserStatus dispenserStatus = (DisppenserStatus)mrkStatus.DispenserStatus;
                string           str2            = "Продажа карт запрещена: ";
                string           format          = "Стоимость карты при получении: {0} РУБ.{1}Наличие карт в терминале: {2}";
                decimal          num             = mrkStatus.CardPrice / 100M;
                switch (dispenserStatus)
                {
                case DisppenserStatus.DispenserError:
                    Logger(str2 + "диспенсер не работает", EventEntryType.Error);
                    result = DisppenserStatus.DispenserError;
                    break;

                case DisppenserStatus.NoCard:
                    Logger(string.Format(format, num, Environment.NewLine, "НЕТ"), EventEntryType.Warning);
                    result = DisppenserStatus.NoCard;
                    break;

                case DisppenserStatus.FewCard:
                case DisppenserStatus.ManyCard:
                    if (!(mrkStatus.CardPrice == 0M))
                    {
                        Logger(string.Format(format, num, Environment.NewLine, "ЕСТЬ"), EventEntryType.Event);
                        result = (DisppenserStatus)mrkStatus.DispenserStatus;
                        break;
                    }
                    Logger(str2 + "цена карты не определена.", EventEntryType.Warning);
                    break;
                }
            }
            return(result);
        }
コード例 #8
0
ファイル: ServioCardsShell.cs プロジェクト: mi1vus/PCSC_test
        // ОПЕРАЦИЯ ПО КАРТЕ
        /// <summary>
        /// ОПЕРАЦИЯ ПО КАРТЕ
        /// </summary>
        /// <param name="type">тип операции</param>
        /// <param name="terminal">терминал (азс)</param>
        /// <param name="transact">номер транзакции</param>
        /// <param name="opItem">параметры операции</param>
        /// <returns></returns>
        public static ServioCardInfo CardOperationExecute(CardOperationType type, int terminal, long transact, CardOperationItem opItem)
        {
            ServioCardInfo res = new ServioCardInfo {
                ErrorCore = -1, CardNumber = "", IssuerID = -1
            };
            IntPtr obj = new IntPtr();

            IntPtr serialNumberPtr = Marshal.AllocHGlobal(sizeof(SerialnumberT));
            IntPtr cardImagePtr    = Marshal.AllocHGlobal(sizeof(Mf1S70T));
            IntPtr operationPtr    = CardOperation_Create();

            try
            {
                if ((res.ErrorCore = InitInternal(_config, ref obj)) != (int)ErrorCodes.ESuccess)
                {
                    if (res.ErrorCore == (int)ErrorCodes.ECancel)
                    {
                        return(res);
                    }
                    throw new CardShellException("Error Init No" + res, res.ErrorCore);
                }
                UnMemory <byte> .SaveInMemArr(new byte[Mf1S70T.Size], ref cardImagePtr);

                if ((res.ErrorCore = ReadCard(obj, serialNumberPtr, cardImagePtr, false)) != (int)ErrorCodes.ESuccess)
                {
                    if (res.ErrorCore == (int)ErrorCodes.ECancel)
                    {
                        return(res);
                    }
                    throw new CardShellException("Error ReadCard No" + res, res.ErrorCore);
                }
                var operation = UnMemory <CardOperation> .ReadInMem(operationPtr);

                SerialnumberT serialNumber = UnMemory <SerialnumberT> .ReadInMem(serialNumberPtr);

                operation.Size           = sizeof(CardOperation);
                operation.OpCode         = (byte)OperationSelector(type);
                operation.POS            = terminal;                // Номер АЗС или терминала
                operation.OpTime         = DateTime.Now.ToOADate(); // Реальное время с вашего терминала
                operation.TransactID     = transact;                // Тут желательно ваш код код транзакции указать
                operation.CardType       = (int)CardType.CtPayment; // Предположим что тип карты неизвестен
                operation.SerialNumber   = serialNumber;            // Указать серийный номер, считанный с метки
                operation.IssuerID       = -1;                      // Указать -1, программа сама переопределит. Если указать другой код - программа будет использовать его
                operation.CardNumber     = "";                      // Не указывать !!!
                operation.AddPrefixZeros = 0;                       // Нужна доп. настройка. Аналогичная нашей опции в обработчиках
                operation.ItemCount      = 1;                       // При аутентификации позиции не заполнять.

                IntPtr pItem1 = Marshal.AllocHGlobal(sizeof(CardOperationItem));
                UnMemory <CardOperationItem> .SaveInMem(opItem, ref pItem1);

                IntPtr ppItem1 = Marshal.AllocHGlobal(sizeof(IntPtr));
                UnMemory <IntPtr> .SaveInMem(pItem1, ref ppItem1);

                operation.Items = ppItem1;

                UnMemory <CardOperation> .SaveInMem(operation, ref operationPtr);

                if ((res.ErrorCore =
                         OperationSelector(type, obj, serialNumberPtr, cardImagePtr, operationPtr))
                    != (int)ErrorCodes.ESuccess)
                {
                    throw new CardShellException("Error Operation No" + res, res.ErrorCore);
                }

                // флаг указывает на то что образ карты был изменен в процессе операции
                // и нужно записать его обратно.
                // Нужно для пополнения карты при просмотре информации
                operation = UnMemory <CardOperation> .ReadInMem(operationPtr);

                if (operation.CardImageChanged != 0)
                {
                    // при ошибке можно попробовать повторить операцию несколько раз 3-10...
                    // если не проходит то это патовая ситуация и для её дальнейшего
                    // разрешения нужно сохранить SerialNumber, CardImage и CardInfo
                    // В теории, сохранённый SerialNumber и CardImage можно попробовать
                    // записать обратно даже при перезапуске ПО, но до следующего
                    // обслуживания по карте. Чтобы решить ситуацию можно сохранить CardInfo
                    // чтобы в офисе уменьшили или увеличили баланс карты на соотв. значение.
                    if ((res.ErrorCore = WriteCard(obj, serialNumberPtr, cardImagePtr)) != (int)ErrorCodes.ESuccess)
                    {
                        throw new CardShellException("Error WriteCard No" + res, res.ErrorCore);
                    }
                }

                operation    = (CardOperation)Marshal.PtrToStructure(operationPtr, typeof(CardOperation));
                res.CardInfo = operation.CheckImage;
                return(res);
            }
            finally
            {
                //CardOperation_Free(operationPtr);
                UnMemory.FreeIntPtr(serialNumberPtr);
                UnMemory.FreeIntPtr(cardImagePtr);
                //MarshalHelper.UnMemory.FreeIntPtr(operationPtr);
            }
        }