diff --git a/pos/is4c-nf/cc-modules/BasicCCModule.php b/pos/is4c-nf/cc-modules/BasicCCModule.php
index a523c25b4d..4c5782579f 100644
--- a/pos/is4c-nf/cc-modules/BasicCCModule.php
+++ b/pos/is4c-nf/cc-modules/BasicCCModule.php
@@ -341,7 +341,7 @@ function soapify($action,$objs,$namespace="",$encode_tags=True){
function desoapify($action,$soaptext){
preg_match("/<$action.*?>(.*?)<\/$action>/s",
$soaptext,$groups);
- return $groups[1];
+ return isset($groups[1]) ? $groups[1] : "";
}
/**
diff --git a/pos/is4c-nf/graphics/ccInLit.gif b/pos/is4c-nf/graphics/ccInLit.gif
new file mode 100755
index 0000000000..c631a65250
Binary files /dev/null and b/pos/is4c-nf/graphics/ccInLit.gif differ
diff --git a/pos/is4c-nf/graphics/ccTestLit.gif b/pos/is4c-nf/graphics/ccTestLit.gif
new file mode 100755
index 0000000000..ac5b87da7b
Binary files /dev/null and b/pos/is4c-nf/graphics/ccTestLit.gif differ
diff --git a/pos/is4c-nf/gui-class-lib/BasicPage.php b/pos/is4c-nf/gui-class-lib/BasicPage.php
index 4130c6ec5e..bb63db9bb9 100644
--- a/pos/is4c-nf/gui-class-lib/BasicPage.php
+++ b/pos/is4c-nf/gui-class-lib/BasicPage.php
@@ -57,8 +57,7 @@ function BasicPage(){
if ($this->preprocess()){
ob_start();
$this->print_page();
- while (ob_get_level() > 0)
- ob_end_flush();
+ ob_end_flush();
}
}
@@ -239,10 +238,16 @@ function betterDate() {
}
if($CORE_LOCAL->get("CCintegrate") == 1 &&
$CORE_LOCAL->get("ccLive") == 1 && $CORE_LOCAL->get("training") == 0){
- echo " ";
+ if ($CORE_LOCAL->get("CachePanEncBlock")=="")
+ echo " ";
+ else
+ echo " ";
}elseif($CORE_LOCAL->get("CCintegrate") == 1 &&
($CORE_LOCAL->get("training") == 1 || $CORE_LOCAL->get("ccLive") == 0)){
- echo " ";
+ if ($CORE_LOCAL->get("CachePanEncBlock")=="")
+ echo " ";
+ else
+ echo " ";
}
echo "".$time."\n";
diff --git a/pos/is4c-nf/gui-modules/paycardSuccess.php b/pos/is4c-nf/gui-modules/paycardSuccess.php
index 56c5cca69a..f8709adc6e 100755
--- a/pos/is4c-nf/gui-modules/paycardSuccess.php
+++ b/pos/is4c-nf/gui-modules/paycardSuccess.php
@@ -72,6 +72,7 @@ function preprocess(){
}
PaycardLib::paycard_reset();
+ UdpComm::udpSend("termReset");
$CORE_LOCAL->set("strRemembered","TO");
$CORE_LOCAL->set("msgrepeat",1);
@@ -188,6 +189,7 @@ function body_content(){
echo DisplayLib::boxMsg($CORE_LOCAL->get("boxMsg"),"",True);
$CORE_LOCAL->set("msgrepeat",2);
//UdpComm::udpSend('goodBeep');
+ UdpComm::udpSend('termApproved');
?>
WriteToScale($CORE_LOCAL->get("ccTermOut"));
PaycardLib::paycard_reset();
+ $CORE_LOCAL->set("CachePanEncBlock","");
+ $CORE_LOCAL->set("CachePinEncBlock","");
+ $CORE_LOCAL->set("CacheCardType","");
+ UdpComm::udpSend("termReset");
$this->change_page($this->page_url."gui-modules/pos2.php");
return False;
}
@@ -100,7 +104,10 @@ function body_content(){
echo PaycardLib::paycard_msgBox($type,"Invalid Amount",
"Enter a lesser amount","[clear] to cancel");
} else if( $amt > 0) {
- echo PaycardLib::paycard_msgBox($type,"Tender ".PaycardLib::paycard_moneyFormat($amt)."?","","[enter] to continue if correct
Enter a different amount if incorrect
[clear] to cancel");
+ $msg = "Tender ".PaycardLib::paycard_moneyFormat($amt);
+ if ($CORE_LOCAL->get("CacheCardType") != "")
+ $msg .= " as ".$CORE_LOCAL->get("CacheCardType");
+ echo PaycardLib::paycard_msgBox($type,$msg."?","","[enter] to continue if correct
Enter a different amount if incorrect
[clear] to cancel");
} else if( $amt < 0) {
echo PaycardLib::paycard_msgBox($type,"Refund ".PaycardLib::paycard_moneyFormat($amt)."?","","[enter] to continue if correct
Enter a different amount if incorrect
[clear] to cancel");
} else {
diff --git a/pos/is4c-nf/gui-modules/pos2.php b/pos/is4c-nf/gui-modules/pos2.php
index fdf5473369..57e6ca6dd8 100644
--- a/pos/is4c-nf/gui-modules/pos2.php
+++ b/pos/is4c-nf/gui-modules/pos2.php
@@ -194,8 +194,7 @@ function receiptFetch(r_type){
});
}
function inputRetry(str){
- $('#reginput').val(str);
- submitWrapper();
+ parseWrapper(str);
}
set("ccRemoteServerUp",1);
$CORE_LOCAL->set("search_or_list",0);
$CORE_LOCAL->set("ccTermOut","idle");
- $td = SigCapture::term_object();
- if (is_object($td))
- $td->WriteToScale("reset");
}
/**
@@ -145,6 +142,10 @@ static public function transReset() {
$CORE_LOCAL->set("warned",0);
$CORE_LOCAL->set("warnBoxType","");
$CORE_LOCAL->set("requestType","");
+
+ $CORE_LOCAL->set("CachePanEncBlock","");
+ $CORE_LOCAL->set("CachePinEncBlock","");
+ $CORE_LOCAL->set("CacheCardType","");
}
/**
diff --git a/pos/is4c-nf/parser-class-lib/parse/SigTermCommands.php b/pos/is4c-nf/parser-class-lib/parse/SigTermCommands.php
index 8d096780b9..1c27c44bc9 100644
--- a/pos/is4c-nf/parser-class-lib/parse/SigTermCommands.php
+++ b/pos/is4c-nf/parser-class-lib/parse/SigTermCommands.php
@@ -25,12 +25,33 @@ class SigTermCommands extends Parser {
function check($str){
global $CORE_LOCAL;
- if ($str == "TRESET"){
- $CORE_LOCAL->set("ccTermOut","reset");
+ if ($str == "TERMMANUAL"){
+ UdpComm::udpSend("termManual");
return True;
}
- if ($str == "TSIG"){
- $CORE_LOCAL->set("ccTermOut","sig");
+ elseif ($str == "TERMRESET"){
+ UdpComm::udpSend("termReset");
+ return True;
+ }
+ elseif ($str == "CCFROMCACHE"){
+ return True;
+ }
+ else if (substr($str,0,9) == "PANCACHE:"){
+ $CORE_LOCAL->set("CachePanEncBlock",substr($str,9));
+ return True;
+ }
+ else if (substr($str,0,9) == "PINCACHE:"){
+ $CORE_LOCAL->set("CachePinEncBlock",substr($str,9));
+ return True;
+ }
+ else if ($str == "TERMCLEARALL"){
+ $CORE_LOCAL->set("CachePanEncBlock","");
+ $CORE_LOCAL->set("CachePinEncBlock","");
+ $CORE_LOCAL->set("CacheCardType","");
+ return True;
+ }
+ else if (substr($str,0,5) == "TERM:"){
+ $CORE_LOCAL->set("CacheCardType",substr($str,5));
return True;
}
return False;
@@ -39,9 +60,9 @@ function check($str){
function parse($str){
global $CORE_LOCAL;
$ret = $this->default_json();
- $ret['udpmsg'] = $CORE_LOCAL->get("ccTermOut");
- if ($ret['udpmsg'] == "sig")
- $ret['main_frame'] = MiscLib::base_url().'gui-modules/paycardSignature.php';
+ if ($str == "CCFROMCACHE"){
+ $ret['retry'] = $CORE_LOCAL->get("CachePanEncBlock");
+ }
return $ret;
}
@@ -51,13 +72,26 @@ function doc(){
Input | Result |
- WAKEUP |
- Try to coax a stuck scale back
- into operation |
+ TERMMANUAL |
+
+ Send CC terminal to manual entry mode
+ |
+
+
+ TERMRESET |
+ Reset CC terminal to begin transaction |
+
+
+ CCFROMCACHE |
+ Charge the card cached earlier |
+
+
+ PANCACHE: |
+ Cache an encrypted block on swipe |
- WAKEUP2 |
- Different method, same goal |
+ PINCACHE: |
+ Cache an encrypted block on PIN entry |
";
}
diff --git a/pos/is4c-nf/scale-drivers/drivers/NewMagellan/SPH_SignAndPay_USB.cs b/pos/is4c-nf/scale-drivers/drivers/NewMagellan/SPH_SignAndPay_USB.cs
index 7ebaf23a71..57bf909f73 100755
--- a/pos/is4c-nf/scale-drivers/drivers/NewMagellan/SPH_SignAndPay_USB.cs
+++ b/pos/is4c-nf/scale-drivers/drivers/NewMagellan/SPH_SignAndPay_USB.cs
@@ -56,12 +56,36 @@ public class SPH_SignAndPay_USB : SerialPortHandler {
private FileStream usb_fs;
private int usb_report_size;
+ private const int LCD_X_RES = 320;
+ private const int LCD_Y_RES = 240;
+
+ private const int STATE_START_TRANSACTION = 1;
+ private const int STATE_SELECT_CARD_TYPE = 2;
+ private const int STATE_ENTER_PIN = 3;
+ private const int STATE_WAIT_FOR_CASHIER = 4;
+ private const int STATE_SELECT_EBT_TYPE = 5;
+ private const int STATE_MANUAL_PAN = 11;
+ private const int STATE_MANUAL_EXP = 12;
+ private const int STATE_MANUAL_CVV = 13;
+
+ private const int BUTTON_CREDIT = 5;
+ private const int BUTTON_DEBIT = 6;
+ private const int BUTTON_EBT = 7;
+ private const int BUTTON_GIFT = 8;
+ private const int BUTTON_EBT_FOOD = 9;
+ private const int BUTTON_EBT_CASH = 10;
+ private const int BUTTON_HARDWARE_BUTTON = 0xff;
+
+ private int current_state;
+ private int ack_counter;
+
private string usb_devicefile;
public SPH_SignAndPay_USB(string p) : base(p){
read_continues = false;
long_length = 0;
long_pos = 0;
+ ack_counter = 0;
#if MONO
usb_devicefile = p;
@@ -85,9 +109,110 @@ public override void Read(){
System.Console.WriteLine("No device");
else
System.Console.WriteLine("USB device found");
- byte[] version = BuildCommand(new byte[]{0x78,0x46,0x01});
- SendReport(version);
+ //SendReport(BuildCommand(LcdSetBacklightTimeout(0)));
ReRead();
+ SetStateStart();
+ //SetStateCardType();
+ }
+
+ private void SetStateStart(){
+ PushOutput("TERMCLEARALL");
+ SendReport(BuildCommand(LcdStopCapture()));
+ SendReport(BuildCommand(PinpadCancelGetPIN()));
+ SendReport(BuildCommand(LcdFillColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdFillRectangle(0,0,LCD_X_RES-1,LCD_Y_RES-1)));
+
+ SendReport(BuildCommand(LcdTextFont(3,12,14)));
+ SendReport(BuildCommand(LcdTextColor(0,0,0)));
+ SendReport(BuildCommand(LcdTextBackgroundColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdTextBackgroundMode(false)));
+ SendReport(BuildCommand(LcdDrawText("andy is awesome",5,5)));
+ SendReport(BuildCommand(LcdDrawText("swipe card",75,100)));
+
+ current_state = STATE_START_TRANSACTION;
+ }
+
+ private void SetStateCardType(){
+ SendReport(BuildCommand(LcdFillColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdFillRectangle(0,0,LCD_X_RES-1,LCD_Y_RES-1)));
+
+ SendReport(BuildCommand(LcdStopCapture()));
+ SendReport(BuildCommand(LcdClearSignature()));
+ SendReport(BuildCommand(LcdSetClipArea(0,0,1,1)));
+ SendReport(BuildCommand(LcdCreateButton(BUTTON_CREDIT,"Credit",5,5,95,95)));
+ SendReport(BuildCommand(LcdCreateButton(BUTTON_DEBIT,"Debit",224,5,314,95)));
+ SendReport(BuildCommand(LcdCreateButton(BUTTON_EBT,"EBT",5,144,95,234)));
+ //SendReport(BuildCommand(LcdCreateButton(BUTTON_GIFT,"Gift",224,144,314,234)));
+ SendReport(BuildCommand(LcdStartCapture(4)));
+
+ current_state = STATE_SELECT_CARD_TYPE;
+ }
+
+ private void SetStateEbtType(){
+ SendReport(BuildCommand(LcdFillColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdFillRectangle(0,0,LCD_X_RES-1,LCD_Y_RES-1)));
+
+ SendReport(BuildCommand(LcdStopCapture()));
+ SendReport(BuildCommand(LcdClearSignature()));
+ SendReport(BuildCommand(LcdSetClipArea(0,0,1,1)));
+ SendReport(BuildCommand(LcdCreateButton(BUTTON_EBT_FOOD,"Food Side",5,5,115,95)));
+ SendReport(BuildCommand(LcdCreateButton(BUTTON_EBT_CASH,"Cash Side",204,5,314,95)));
+ SendReport(BuildCommand(LcdStartCapture(4)));
+
+ current_state = STATE_SELECT_EBT_TYPE;
+ }
+
+ private void SetStateGetPin(){
+ SendReport(BuildCommand(LcdStopCapture()));
+ ack_counter = 0;
+
+ SendReport(BuildCommand(PinpadGetPIN()));
+ current_state = STATE_ENTER_PIN;
+ }
+
+ private void SetStateWaitForCashier(){
+ SendReport(BuildCommand(LcdStopCapture()));
+ SendReport(BuildCommand(LcdFillColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdFillRectangle(0,0,LCD_X_RES-1,LCD_Y_RES-1)));
+
+ SendReport(BuildCommand(LcdTextFont(3,12,14)));
+ SendReport(BuildCommand(LcdTextColor(0,0,0)));
+ SendReport(BuildCommand(LcdTextBackgroundColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdTextBackgroundMode(false)));
+ SendReport(BuildCommand(LcdDrawText("wait for cashier",75,100)));
+
+ current_state = STATE_WAIT_FOR_CASHIER;
+ }
+
+ private void SetStateApproved(){
+ SendReport(BuildCommand(LcdStopCapture()));
+ SendReport(BuildCommand(LcdFillColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdFillRectangle(0,0,LCD_X_RES-1,LCD_Y_RES-1)));
+
+ SendReport(BuildCommand(LcdTextFont(3,12,14)));
+ SendReport(BuildCommand(LcdTextColor(0,0,0)));
+ SendReport(BuildCommand(LcdTextBackgroundColor(0xff,0xff,0xff)));
+ SendReport(BuildCommand(LcdTextBackgroundMode(false)));
+ SendReport(BuildCommand(LcdDrawText("approved",75,100)));
+ }
+
+ private void SetStateGetManualPan(){
+ SendReport(BuildCommand(LcdStopCapture()));
+ ack_counter = 0;
+ SendReport(BuildCommand(ManualEntryPAN()));
+ current_state = STATE_MANUAL_PAN;
+ }
+
+ private void SetStateGetManualExp(){
+ ack_counter = 0;
+ SendReport(BuildCommand(ManualEntryExp()));
+ current_state = STATE_MANUAL_EXP;
+ }
+
+ private void SetStateGetManualCVV(){
+ ack_counter = 0;
+ SendReport(BuildCommand(ManualEntryCVV()));
+ current_state = STATE_MANUAL_CVV;
}
private void ReadCallback(IAsyncResult iar){
@@ -97,8 +222,6 @@ private void ReadCallback(IAsyncResult iar){
}
catch (Exception ex){}
- // prepend extra byte if report size is 64
- // then parsing is identical for win32/linux
if (usb_report_size == 64){
byte[] temp_in = new byte[65];
temp_in[0] = 0;
@@ -109,10 +232,10 @@ private void ReadCallback(IAsyncResult iar){
/* Data received, as bytes
System.Console.WriteLine("");
- System.Console.WriteLine("");
+ System.Console.WriteLine("IN BYTES:");
for(int i=0;i0 && i %16==0) System.Console.WriteLine("");
- System.Console.Write(input[i]+" ");
+ System.Console.Write("{0:x} ",input[i]);
}
System.Console.WriteLine("");
System.Console.WriteLine("");
@@ -127,11 +250,12 @@ private void ReadCallback(IAsyncResult iar){
if ( (input[1] & 0x80) != 0)
read_continues = true;
- if (report_length > 3){
+ byte[] data = null;
+ if (report_length > 3 && (long_pos > 0 || input[2] == 0x02)){ // protcol messages
int data_length = input[3] + (input[4] << 8);
int d_start = 5;
- if (input[d_start] == 0x6){
+ if (input[d_start] == 0x6 && data_length > 1){
d_start++; // ACK byte
data_length--;
}
@@ -154,7 +278,7 @@ private void ReadCallback(IAsyncResult iar){
if (data_length > report_length) data_length = report_length;
- byte[] data = new byte[data_length];
+ data = new byte[data_length];
for (int i=0; i 3){ // non-protcol messages
+ data = new byte[report_length];
+ for(int i=0; i0 && i %16==0) System.Console.WriteLine("");
- System.Console.Write(long_buffer[i]+" ");
- }
- */
+
+ HandleDeviceMessage(long_buffer);
+ }
+ else {
+ HandleDeviceMessage(data);
}
read_continues = false;
long_length = 0;
@@ -211,12 +331,136 @@ private void ReadCallback(IAsyncResult iar){
ReRead();
}
+ private void HandleDeviceMessage(byte[] msg){
+ System.Console.Write("DMSG: {0}: ",current_state);
+ 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){
+ if (msg[1] == BUTTON_CREDIT){
+ PushOutput("TERM:Credit");
+ SetStateWaitForCashier();
+ }
+ else if (msg[1] == BUTTON_DEBIT){
+ PushOutput("TERM:Debit");
+ SetStateGetPin();
+ }
+ else if (msg[1] == BUTTON_EBT){
+ SetStateEbtType();
+ }
+ else if (msg[1] == BUTTON_GIFT){
+ PushOutput("TERM:Gift");
+ SetStateWaitForCashier();
+ }
+ else if (msg[1] == BUTTON_HARDWARE_BUTTON && msg[3] == 0x43){
+ SetStateStart();
+ }
+ }
+ break;
+ case STATE_SELECT_EBT_TYPE:
+ if (msg.Length == 4 && msg[0] == 0x7a){
+ if (msg[1] == BUTTON_EBT_FOOD){
+ PushOutput("TERM:EbtFood");
+ SetStateGetPin();
+ }
+ else if (msg[1] == BUTTON_EBT_CASH){
+ PushOutput("TERM:EbtCash");
+ SetStateGetPin();
+ }
+ else if (msg[1] == BUTTON_HARDWARE_BUTTON && msg[3] == 0x43){
+ SetStateStart();
+ }
+ }
+ break;
+ case STATE_ENTER_PIN:
+ if (msg.Length == 3 && msg[0] == 0x15){
+ SetStateStart();
+ }
+ else if (msg.Length == 36){
+ string pinhex = "";
+ foreach(byte b in msg)
+ pinhex += ((char)b);
+ PushOutput("PINCACHE:"+pinhex);
+ SetStateWaitForCashier();
+ }
+ break;
+ case STATE_MANUAL_PAN:
+ if (msg.Length == 1 && msg[0] == 0x6){
+ ack_counter++;
+ System.Console.WriteLine(ack_counter);
+ if (ack_counter == 2)
+ SetStateGetManualExp();
+ }
+ else if (msg.Length == 3 && msg[0] == 0x15){
+ SetStateStart();
+ }
+ break;
+ case STATE_MANUAL_EXP:
+ if (msg.Length == 1 && msg[0] == 0x6){
+ ack_counter++;
+ 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 && msg[1] == 0x1f){
+ 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 && msg[1] == 0x1f){
+ string block = FixupCardBlock(msg);
+ PushOutput("PANCACHE:"+block);
+ SetStateCardType();
+ }
+ else if (msg.Length > 1)
+ System.Console.WriteLine(msg.Length+" "+msg[0]+" "+msg[1]);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Convert encrypted card block to a hex string
+ * and add the serial protcol controcl characters back
+ * to the beginning and end. PHP-side software expects
+ * this format
+ */
+ private string FixupCardBlock(byte[] data){
+ string hex = BitConverter.ToString(data).Replace("-","");
+ hex = "02E600"+hex+"XXXX03";
+ return hex;
+ }
+
private void ReRead(){
byte[] buf = new byte[usb_report_size];
usb_fs.BeginRead(buf, 0, usb_report_size, new AsyncCallback(ReadCallback), buf);
}
public override void HandleMsg(string msg){
+ switch(msg){
+ case "termReset":
+ SetStateStart();
+ break;
+ case "termManual":
+ SetStateGetManualPan();
+ break;
+ case "termApproved":
+ SetStateApproved();
+ break;
+ }
}
/**
@@ -287,6 +531,15 @@ private byte LrcXor(byte[] data){
* Write to device in formatted reports
*/
private void SendReport(byte[] data){
+ System.Console.WriteLine("Full Report "+data.Length);
+ for(int j=0;j 0)
+ System.Console.WriteLine("");
+ System.Console.Write("{0:x} ",data[j]);
+ }
+ System.Console.WriteLine("");
+ System.Console.WriteLine("");
+
byte[] report = new byte[usb_report_size];
int size_field = (usb_report_size == 65) ? 1 : 0;
@@ -296,22 +549,36 @@ private void SendReport(byte[] data){
for (int i=0;i 0 && i % 63 == 0){
report[size_field] = 63 | 0x80;
+
+ /*
+ for(int j=0;j 0)
+ System.Console.WriteLine("");
+ System.Console.Write(report[j]+" ");
+ }
+ System.Console.WriteLine("");
+ */
+
usb_fs.Write(report,0,usb_report_size);
+
for(int j=0;j 0)
System.Console.WriteLine("");
System.Console.Write(report[i]+" ");
}
System.Console.WriteLine("");
+ */
usb_fs.Write(report,0,usb_report_size);
+ System.Threading.Thread.Sleep(50);
}
private void PushOutput(string s){
@@ -328,6 +595,725 @@ private void PushOutput(string s){
MAGELLAN_OUTPUT_DIR+sep+ticks);
}
+ /**
+ * Device Command Functions
+ */
+
+ private byte[] LcdTextFont(int charset, int width, int height){
+ byte[] ret = new byte[9];
+
+ // command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x40;
+
+ ret[3] = (byte)(0xff & height);
+ ret[4] = (byte)(0xff & width);
+ ret[5] = 0x0; // bold
+ ret[6] = 0x0; // italic
+ ret[7] = 0x0; // underlined
+ ret[8] = (charset > 6) ? (byte)6 : (byte)charset;
+
+ return ret;
+ }
+
+ private byte[] LcdTextColor(int red, int green, int blue){
+ byte[] ret = new byte[6];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x41;
+
+ ret[3] = (byte)(red & 0xff);
+ ret[4] = (byte)(green & 0xff);
+ ret[5] = (byte)(blue & 0xff);
+
+ return ret;
+ }
+
+ private byte[] LcdTextBackgroundColor(int red, int green, int blue){
+ byte[] ret = new byte[6];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x42;
+
+ ret[3] = (byte)(red & 0xff);
+ ret[4] = (byte)(green & 0xff);
+ ret[5] = (byte)(blue & 0xff);
+
+ return ret;
+ }
+
+ private byte[] LcdTextBackgroundMode(bool is_transparent){
+ byte[] ret = new byte[4];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x43;
+
+ ret[3] = (is_transparent) ? (byte)1 : (byte)0;
+
+ return ret;
+ }
+
+ private byte[] LcdDrawText(string text, int x, int y){
+ byte[] ret = new byte[9 + text.Length];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x4f;
+
+ ret[3] = (byte)(x & 0xff);
+ ret[4] = (byte)( (x >> 8) & 0xff);
+
+ ret[5] = (byte)(y & 0xff);
+ ret[6] = (byte)( (y >> 8) & 0xff);
+
+ ret[7] = (byte)(text.Length & 0xff);
+ ret[8] = (byte)( (text.Length >> 8) & 0xff);
+
+ int pos = 9;
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(text)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ return ret;
+ }
+
+ private byte[] LcdDrawTextInRectangle(string text, int x_top_left, int y_top_left,
+ int x_bottom_right, int y_bottom_right){
+
+ byte[] ret = new byte[13 + text.Length];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x4e;
+
+ ret[3] = (byte)(x_top_left & 0xff);
+ ret[4] = (byte)( (x_top_left >> 8) & 0xff);
+
+ ret[5] = (byte)(y_top_left & 0xff);
+ ret[6] = (byte)( (y_top_left >> 8) & 0xff);
+
+ ret[7] = (byte)(x_bottom_right & 0xff);
+ ret[8] = (byte)( (x_bottom_right >> 8) & 0xff);
+
+ ret[9] = (byte)(y_bottom_right & 0xff);
+ ret[10] = (byte)( (y_bottom_right >> 8) & 0xff);
+
+ ret[11] = (byte)(text.Length & 0xff);
+ ret[12] = (byte)( (text.Length >> 8) & 0xff);
+
+ int pos = 13;
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(text)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ return ret;
+ }
+
+ private byte[] LcdFillColor(int red, int green, int blue){
+ byte[] ret = new byte[6];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x20;
+
+ ret[3] = (byte)(0xff & red);
+ ret[4] = (byte)(0xff & green);
+ ret[5] = (byte)(0xff & blue);
+
+ return ret;
+ }
+
+ private byte[] LcdFillRectangle(int x_top_left, int y_top_left,
+ int x_bottom_right, int y_bottom_right){
+ byte[] ret = new byte[11];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x46;
+ ret[2] = 0x22;
+
+ ret[3] = (byte)(x_top_left & 0xff);
+ ret[4] = (byte)( (x_top_left >> 8) & 0xff);
+
+ ret[5] = (byte)(y_top_left & 0xff);
+ ret[6] = (byte)( (y_top_left >> 8) & 0xff);
+
+ ret[7] = (byte)(x_bottom_right & 0xff);
+ ret[8] = (byte)( (x_bottom_right >> 8) & 0xff);
+
+ ret[9] = (byte)(y_bottom_right & 0xff);
+ ret[10] = (byte)( (y_bottom_right >> 8) & 0xff);
+
+ return ret;
+ }
+
+ /**
+ * @param interval is five second periods.
+ * 1=> 5 seconds, 2=> 10 seconds, etc
+ * 0=> always on
+ */
+ private byte[] LcdSetBacklightTimeout(int interval){
+ byte[] ret = new byte[5];
+
+ // Command head
+ ret[0] = 0x8a;
+ ret[1] = 0x53;
+ ret[2] = 0x80;
+
+ ret[3] = 0x1;
+ ret[4] = (byte)(interval & 0xff);
+
+ return ret;
+ }
+
+ private byte[] LcdSetClipArea(int x_top_left, int y_top_left, int x_bottom_right, int y_bottom_right){
+ byte[] ret = new byte[15];
+
+ // Command head
+ ret[0] = 0x7a;
+ ret[1] = 0x46;
+ ret[2] = 0x03;
+
+ ret[3] = (byte)(x_top_left & 0xff);
+ ret[4] = (byte)( (x_top_left >> 8) & 0xff);
+
+ ret[5] = (byte)(y_top_left & 0xff);
+ ret[6] = (byte)( (y_top_left >> 8) & 0xff);
+
+ ret[7] = (byte)(x_bottom_right & 0xff);
+ ret[8] = (byte)( (x_bottom_right >> 8) & 0xff);
+
+ ret[9] = (byte)(y_bottom_right & 0xff);
+ ret[10] = (byte)( (y_bottom_right >> 8) & 0xff);
+
+ ret[11] = 0x0; // don't show lines around area
+
+ // rgb for border lines
+ ret[12] = 0x0;
+ ret[13] = 0x0;
+ ret[14] = 0x0;
+
+ return ret;
+ }
+
+ private byte[] LcdCreateButton(int id, string label, int x_top_left, int y_top_left,
+ int x_bottom_right, int y_bottom_right){
+
+ byte[] ret = new byte[16 + label.Length];
+
+ // Command head
+ ret[0] = 0x7a;
+ ret[1] = 0x46;
+ ret[2] = 0x04;
+
+ ret[3] = (byte)(id & 0xff);
+ ret[4] = 0x1; // button is type 1
+ ret[5] = 0xf;
+
+ ret[6] = (byte)(x_top_left & 0xff);
+ ret[7] = (byte)( (x_top_left >> 8) & 0xff);
+
+ ret[8] = (byte)(y_top_left & 0xff);
+ ret[9] = (byte)( (y_top_left >> 8) & 0xff);
+
+ ret[10] = (byte)(x_bottom_right & 0xff);
+ ret[11] = (byte)( (x_bottom_right >> 8) & 0xff);
+
+ ret[12] = (byte)(y_bottom_right & 0xff);
+ ret[13] = (byte)( (y_bottom_right >> 8) & 0xff);
+
+ ret[14] = (byte)(label.Length & 0xff);
+ ret[15] = (byte)( (label.Length >> 8) & 0xff);
+
+ int pos = 16;
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(label)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ return ret;
+ }
+
+ private byte[] LcdCalibrateTouch(){
+ return new byte[3]{ 0x7a, 0x46, 0x1 };
+ }
+
+ /**
+ * Mode 5 => buffered
+ * Mode < 5 => streaming data
+ */
+ private byte[] LcdStartCapture(int mode){
+ byte[] ret = new byte[11];
+
+ ret[0] = 0x7a;
+ ret[1] = 0x46;
+ ret[2] = 0x10;
+
+ ret[3] = (byte)(0xff & mode);
+
+ ret[4] = 0x7a;
+
+ ret[5] = 0x0;
+ ret[6] = 0x0;
+ ret[7] = 0x0;
+
+ ret[8] = 0xff;
+ ret[9] = 0xff;
+ ret[10] = 0xff;
+
+ return ret;
+ }
+
+ private byte[] LcdClearSignature(){
+ return new byte[3]{ 0x7a, 0x46, 0x19 };
+ }
+
+ private byte[] LcdStopCapture(){
+ return new byte[3]{ 0x7a, 0x46, 0x1f };
+ }
+
+ private byte[] PinpadGetPIN(){
+ byte[] ret = new byte[112];
+ int pos = 0;
+
+ // Command head
+ ret[pos++] = 0x75;
+ ret[pos++] = 0x46;
+ ret[pos++] = 0x07;
+
+ ret[pos++] = 0x31; // key type DUKPT
+ ret[pos++] = 0xc; // max pin length
+ ret[pos++] = 0x4; // min pin length
+ ret[pos++] = 0x0; // no account #
+ ret[pos++] = 0x3; // clear display, show messages
+
+ // background color
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xcc;
+
+ // font setting
+ ret[pos++] = 0x16;
+ ret[pos++] = 0x18;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 5;
+
+ // color for something
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0x1; // transparent
+
+ // text color
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // xy set 1
+ ret[pos++] = 0x20;
+ ret[pos++] = 0;
+ ret[pos++] = 0x60;
+ ret[pos++] = 0;
+
+ // xy set 2
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x1;
+ ret[pos++] = 0x90;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0xf; // show 4 lines
+ ret[pos++] = 2; // 2 messages follow
+ ret[pos++] = 0;
+ ret[pos++] = 0x1f; // message length
+ ret[pos++] = 0;
+
+ // another font
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x3;
+
+ // text rgb
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0xff;
+
+ ret[pos++] = 0x1; // transparent
+
+ // background rgb
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // text xy
+ ret[pos++] = 0x40;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x20;
+ ret[pos++] = 0x0;
+
+ // text length
+ ret[pos++] = 0xa;
+ ret[pos++] = 0;
+
+ string msg = "Enter PIN:";
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(msg)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ // next message length
+ ret[pos++] = 0x2e;
+ ret[pos++] = 0x0;
+
+ // another font
+ ret[pos++] = 0xc;
+ ret[pos++] = 0xc;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x3;
+
+ // another rgb
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0xff;
+
+ ret[pos++] = 1; // transparent
+
+ // background rgb
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // xy
+ ret[pos++] = 0x6;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0xb4;
+ ret[pos++] = 0x0;
+
+ // text length
+ ret[pos++] = 0x19;
+ ret[pos++] = 0x0;
+
+ msg = "Press Enter Key When Done";
+
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(msg)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ return ret;
+ }
+
+ private byte[] PinpadCancelGetPIN(){
+ return new byte[3]{ 0x75, 0x46, 0x9 };
+ }
+
+ private byte[] ManualEntryPAN(){
+ byte[] ret = new byte[68];
+
+ int pos = 0;
+ ret[pos++] = 0x75;
+ ret[pos++] = 0x46;
+ ret[pos++] = 0x40;
+
+ ret[pos++] = 0x0; // card type
+ ret[pos++] = 0x1; // PAN mode
+ ret[pos++] = 23; // max length
+ ret[pos++] = 6; // min length
+ ret[pos++] = 0x3; // redraw screen
+
+ // rgb background
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // font setting
+ ret[pos++] = 0x16;
+ ret[pos++] = 0x18;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 5;
+
+ // color for something
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0x1; // transparent
+
+ // text color
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // xy set 1
+ ret[pos++] = 0x20;
+ ret[pos++] = 0;
+ ret[pos++] = 0x60;
+ ret[pos++] = 0;
+
+ // xy set 2
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x1;
+ ret[pos++] = 0x90;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0xf; // show 4 lines
+ ret[pos++] = 1; // 1 messages follow
+ ret[pos++] = 0;
+ ret[pos++] = 33;
+ ret[pos++] = 0;
+
+ // another font
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x3;
+
+ // text rgb
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0xff;
+
+ ret[pos++] = 0x1; // transparent
+
+ // background rgb
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // text xy
+ ret[pos++] = 0x40;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x20;
+ ret[pos++] = 0x0;
+
+ string msg = "Enter Card #";
+ ret[pos++] = 12;
+ ret[pos++] = 0;
+
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(msg)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ return ret;
+ }
+
+ private byte[] ManualEntryExp(){
+ byte[] ret = new byte[70];
+
+ int pos = 0;
+ ret[pos++] = 0x75;
+ ret[pos++] = 0x46;
+ ret[pos++] = 0x40;
+
+ ret[pos++] = 0x0; // card type
+ ret[pos++] = 0x2; // exp mode
+ ret[pos++] = 4; // max length
+ ret[pos++] = 4; // min length
+ ret[pos++] = 0x3; // redraw screen
+
+ // rgb background
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // font setting
+ ret[pos++] = 0x16;
+ ret[pos++] = 0x18;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 5;
+
+ // color for something
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0x1; // transparent
+
+ // text color
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // xy set 1
+ ret[pos++] = 0x20;
+ ret[pos++] = 0;
+ ret[pos++] = 0x60;
+ ret[pos++] = 0;
+
+ // xy set 2
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x1;
+ ret[pos++] = 0x90;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0xf; // show 4 lines
+ ret[pos++] = 1; // 1 messages follow
+ ret[pos++] = 0;
+ ret[pos++] = 35;
+ ret[pos++] = 0;
+
+ // another font
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x3;
+
+ // text rgb
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0xff;
+
+ ret[pos++] = 0x1; // transparent
+
+ // background rgb
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // text xy
+ ret[pos++] = 0x40;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x20;
+ ret[pos++] = 0x0;
+
+ string msg = "Enter Exp MMYY";
+ ret[pos++] = 14;
+ ret[pos++] = 0;
+
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(msg)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ return ret;
+ }
+
+ private byte[] ManualEntryCVV(){
+ byte[] ret = new byte[75];
+
+ int pos = 0;
+ ret[pos++] = 0x75;
+ ret[pos++] = 0x46;
+ ret[pos++] = 0x40;
+
+ ret[pos++] = 0x0; // card type
+ ret[pos++] = 0x3; // CVV mode
+ ret[pos++] = 4; // max length
+ ret[pos++] = 3; // min length
+ ret[pos++] = 0x3; // redraw screen
+
+ // rgb background
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // font setting
+ ret[pos++] = 0x16;
+ ret[pos++] = 0x18;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 5;
+
+ // color for something
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0x1; // transparent
+
+ // text color
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // xy set 1
+ ret[pos++] = 0x20;
+ ret[pos++] = 0;
+ ret[pos++] = 0x60;
+ ret[pos++] = 0;
+
+ // xy set 2
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x1;
+ ret[pos++] = 0x90;
+ ret[pos++] = 0;
+
+ ret[pos++] = 0xf; // show 4 lines
+ ret[pos++] = 1; // 1 messages follow
+ ret[pos++] = 0;
+ ret[pos++] = 40;
+ ret[pos++] = 0;
+
+ // another font
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x10;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x3;
+
+ // text rgb
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0xff;
+
+ ret[pos++] = 0x1; // transparent
+
+ // background rgb
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+ ret[pos++] = 0xff;
+
+ // text xy
+ ret[pos++] = 0x40;
+ ret[pos++] = 0x0;
+ ret[pos++] = 0x20;
+ ret[pos++] = 0x0;
+
+ string msg = "Enter Security Code";
+ ret[pos++] = 19;
+ ret[pos++] = 0;
+
+ foreach(byte b in System.Text.Encoding.ASCII.GetBytes(msg)){
+ ret[pos] = b;
+ pos++;
+ }
+
+ return ret;
+ }
+
+ private byte[] ResetDevice(){
+ return new byte[7]{0x78, 0x46, 0x0a, 0x49, 0x52, 0x46, 0x57};
+ }
}
}