CORE-POS/IS4C

View on GitHub
pos/is4c-nf/scale-drivers/drivers/NewMagellan/SPH_SignAndPay_Auto.cs

Summary

Maintainability
F
5 days
Test Coverage
/*******************************************************************************

    Copyright 2009 Whole Foods Co-op

    This file is part of IT CORE.

    IT CORE is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    IT CORE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    in the file license.txt along with IT CORE; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*********************************************************************************/

using System;
using System.IO;
using System.IO.Ports;
using System.Threading;
using CustomForms;

using USBLayer;

namespace SPH {

public class SPH_SignAndPay_Auto : SPH_SignAndPay_USB 
{

    public SPH_SignAndPay_Auto(string p) : base(p)
    {
        System.Console.WriteLine("Loading Sign and Pay module");
        System.Console.WriteLine("  Screen Control: Auto");
        System.Console.WriteLine("  Paycards Communication: Direct");

        #if MONO
        usb_devicefile = p;
        #endif
    }

    protected override void GetHandle()
    {
        usb_fs = null;
        #if MONO
        usb_port = new USBWrapper_Posix();
        usb_report_size = 64;
        System.Console.WriteLine("  USB Layer: Posix Device File");
        #else
        usb_port = new USBWrapper_Win32();
        usb_report_size = 65;
        System.Console.WriteLine("  USB Layer: Win32");
        #endif
        while(usb_fs == null){
            usb_fs = usb_port.GetUSBHandle(usb_devicefile,usb_report_size);
            if (usb_fs == null){
                if (this.verbose_mode > 0)
                    System.Console.WriteLine("No device");
                System.Threading.Thread.Sleep(5000);
            }
            else { 
                if (this.verbose_mode > 0)
                    System.Console.WriteLine("USB device found");
            }
        }
    }

    public override void Read()
    { 
        PushOutput("TERMAUTOENABLE");

        GetHandle();
        SendReport(BuildCommand(LcdSetBacklightTimeout(0)));
        SendReport(BuildCommand(EnableAudio()));
        /**
          Loading the logo is somewhat time consuming, so you may
          want to change logo_available to true and recompile once
          it's on the device. Otherwise it's loaded onto the device
          each time the driver starts up

          Logo is assumed to be 180x200. Max file size is 32KB.
        */
        if (!this.logo_available && File.Exists("logo.jpg")) {
            SendReport(BuildCommand(LcdStoreImage(1, "logo.jpg")));
            this.logo_available = true;
        }
        SetStateStart();
        #if MONO
        MonoRead();
        #else
        ReRead();
        #endif
    }

    protected override void RebootTerminal()
    {
        try {
            SendReport(BuildCommand(ResetDevice()));
        }
        catch (Exception ex){
            if (this.verbose_mode > 0){
                System.Console.WriteLine("Reboot error:");
                System.Console.WriteLine(ex);
            }
        }
        try {
            usb_fs.Dispose();
        }
        catch (Exception ex){
            if (this.verbose_mode > 0){
                System.Console.WriteLine("Dispose error:");
                System.Console.WriteLine(ex);
            }
        }
        try {
            usb_port.CloseUSBHandle();
        }
        catch (Exception ex){
            if (this.verbose_mode > 0){
                System.Console.WriteLine("Dispose error:");
                System.Console.WriteLine(ex);
            }
        }
        System.Threading.Thread.Sleep(DEFAULT_WAIT_TIMEOUT);
        GetHandle();
        SetStateStart();
        #if MONO
        //MonoRead();
        #else
        ReRead();
        #endif
    }

    /**
      Auto override default behavior and automatically
      switches device state (screen) when receiving
      certain messages from the terminal
    */
    protected override void HandleDeviceMessage(byte[] msg)
    {
        if (this.verbose_mode > 0)
            System.Console.Write("DMSG: {0}: ",current_state);

        if (msg == null) msg = new byte[0];

        if (this.verbose_mode > 0){
            foreach(byte b in msg)
                System.Console.Write("{0:x} ",b);
            System.Console.WriteLine();
        }
        switch(current_state){
        case STATE_SELECT_CARD_TYPE:
            if (msg.Length == 4 && msg[0] == 0x7a){
                SendReport(BuildCommand(DoBeep()));
                if (msg[1] == BUTTON_CREDIT){
                    PushOutput("TERM:Credit");
                    SetStateWaitForCashier();
                }
                else if (msg[1] == BUTTON_DEBIT){
                    PushOutput("TERM:Debit");
                    // automatic state change
                    SetStateCashBack();
                }
                else if (msg[1] == BUTTON_EBT){
                    // purposely autochanged. no message to pos
                    // until ebt sub-selection is made
                    SetStateEbtType();
                }
                else if (msg[1] == BUTTON_GIFT){
                    PushOutput("TERM:Gift");
                    // automatic state change
                    SetStateWaitForCashier();    
                }
                else if (msg[1] == BUTTON_HARDWARE_BUTTON && msg[3] == 0x43){
                    SetStateStart();
                    PushOutput("TERMCLEARALL");
                }
            }
            break;
        case STATE_SELECT_EBT_TYPE:
            if (msg.Length == 4 && msg[0] == 0x7a){
                SendReport(BuildCommand(DoBeep()));
                if (msg[1] == BUTTON_EBT_FOOD){
                    PushOutput("TERM:EbtFood");
                    // automatic state change
                    SetStateGetPin();
                }
                else if (msg[1] == BUTTON_EBT_CASH){
                    PushOutput("TERM:EbtCash");
                    // automatic state change
                    SetStateCashBack();
                }
                else if (msg[1] == BUTTON_HARDWARE_BUTTON && msg[3] == 0x43){
                    SetStateStart();
                    PushOutput("TERMCLEARALL");
                }
            }
            break;
        case STATE_SELECT_CASHBACK:
            if (msg.Length == 4 && msg[0] == 0x7a){
                SendReport(BuildCommand(DoBeep()));
                if (msg[1] == BUTTON_HARDWARE_BUTTON && msg[3] == 0x43){
                    SetStateStart();
                    PushOutput("TERMCLEARALL");
                }
                else if(msg[1] != 0x6){
                    // 0x6 might be a serial protocol ACK
                    // timing issue means we got here too soon
                    // and should wait for next input
    
                    // Pressed green or yellow button
                    // Proceed to PIN entry but don't
                    // request 0xFF as cash back
                    if (msg[1] != BUTTON_HARDWARE_BUTTON)
                        PushOutput("TERMCB:"+msg[1]);
                    // automatic state change
                    SetStateGetPin();
                }
            }
            break;
        case STATE_ENTER_PIN:
            if (msg.Length == 3 && msg[0] == 0x15){
                SetStateStart();
                PushOutput("TERMCLEARALL");
            }
            else if (msg.Length == 36){
                string pinhex = "";
                foreach(byte b in msg)
                    pinhex += ((char)b);
                PushOutput("PINCACHE:"+pinhex);
                // automatic state change
                SetStateWaitForCashier();
            }
            break;
        case STATE_GET_SIGNATURE:
            if (msg.Length == 4 && msg[0] == 0x7a){
                //SendReport(BuildCommand(DoBeep()));
                if (msg[1] == BUTTON_SIG_RESET){
                    SendReport(BuildCommand(LcdClearSignature()));
                }
                else if (msg[1] == BUTTON_SIG_ACCEPT){
                    RemoveSignatureButtons();
                    SendReport(BuildCommand(LcdGetBitmapSig()));
                }
            }
            else if (msg.Length > 2 && msg[0] == 0x42 && msg[1] == 0x4d){
                BitmapOutput(msg);
                sig_message = "";
            }
            break;
        case STATE_MANUAL_PAN:
            if (msg.Length == 1 && msg[0] == 0x6){
                ack_counter++;
                if (this.verbose_mode > 0)
                    System.Console.WriteLine(ack_counter);
                if (ack_counter == 1)
                    SetStateGetManualExp();
            }
            else if (msg.Length == 3 && msg[0] == 0x15){
                SetStateStart();
            }
            break;
        case STATE_MANUAL_EXP:
            if (msg.Length == 1 && msg[0] == 0x6){
                ack_counter++;
                if (this.verbose_mode > 0)
                    System.Console.WriteLine(ack_counter);
                if (ack_counter == 2)
                    SetStateGetManualCVV();
            }
            else if (msg.Length == 3 && msg[0] == 0x15){
                SetStateStart();
            }
            break;
        case STATE_MANUAL_CVV:
            if (msg.Length > 63 && msg[0] == 0x80){
                string block = FixupCardBlock(msg);
                PushOutput("PANCACHE:"+block);
                SetStateCardType();
            }

            else if (msg.Length == 3 && msg[0] == 0x15){
                SetStateStart();
            }
            break;
        case STATE_START_TRANSACTION:
            if (msg.Length > 63 && msg[0] == 0x80 ){
                SendReport(BuildCommand(DoBeep()));
                string block = FixupCardBlock(msg);
                if (block.Length == 0){
                    SetStateReStart();
                }
                else {
                    PushOutput("PANCACHE:"+block);
                    // automatic state change
                    SetStateCardType();
                }
            }
            else if (msg.Length > 1){
                if (this.verbose_mode > 0)
                    System.Console.WriteLine(msg.Length+" "+msg[0]+" "+msg[1]);
            }
            break;
        }
    }

    /**
      Overridden to ignore screen-draw messages
      from POS that are handled automatically.
      Ignored messages are:
      * termGetType
      * termGetTypeWithFS
      * termCashBack
      * termGetPin
      * termWait
    */
    public override void HandleMsg(string msg)
    { 
        // optional predicate for "termSig" message
        // predicate string is displayed on sig capture screen
        if (msg.Length > 7 && msg.Substring(0, 7) == "termSig") {
            sig_message = msg.Substring(7);
            msg = "termSig";
        }

        // 7May13 use locks
        last_message = msg;
        switch(msg){
        case "termReset":
            lock(usb_lock){
                SetStateStart();
            }
            break;
        case "termReboot":
            lock(usb_lock){
                RebootTerminal();
            }
            break;
        case "termManual":
            lock(usb_lock){
                SetStateGetManualPan();
            }
            break;
        case "termSig":
            lock(usb_lock){
                SetStateGetSignature();
            }
            break;
        }
    }
}

}