001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.pos.jpos.service;
019:
020: import jpos.JposException;
021: import jpos.MSRConst;
022: import jpos.JposConst;
023: import jpos.events.DataEvent;
024: import jpos.events.ErrorEvent;
025:
026: import org.ofbiz.pos.adaptor.KeyboardAdaptor;
027: import org.ofbiz.pos.adaptor.KeyboardReceiver;
028:
029: public class MsrKybService extends BaseService implements
030: jpos.services.MSRService17, KeyboardReceiver {
031:
032: public static final String module = MsrKybService.class.getName();
033: public static final int JPOS_MSR_ACCT_ERR = 100;
034: public static final int JPOS_MSR_EXPD_ERR = 101;
035:
036: protected String title = new String();
037: protected String firstname = new String();
038: protected String middle = new String();
039: protected String surname = new String();
040: protected String suffix = new String();
041:
042: protected String[] accountNumber = new String[2];
043: protected String[] expireDate = new String[2];
044: protected String serviceCode = new String();
045:
046: protected byte[] track1DiscretionaryData = new byte[0];
047: protected byte[] track2DiscretionaryData = new byte[0];
048: protected byte[] track1Data = new byte[0];
049: protected byte[] track2Data = new byte[0];
050: protected byte[] track3Data = new byte[0];
051: protected int[] sentinels = new int[0];
052: protected int[] lrc = new int[0];
053:
054: protected boolean parseDecodeData = true;
055: protected boolean decodeData = true;
056: protected boolean autoDisable = false;
057: protected boolean sendSentinels = true;
058:
059: protected int tracksToRead = MSRConst.MSR_TR_1_2_3;
060: protected int errorType = MSRConst.MSR_ERT_CARD;
061:
062: public MsrKybService() {
063: KeyboardAdaptor.getInstance(this , KeyboardAdaptor.MSR_DATA);
064: }
065:
066: // MSRService12
067: public boolean getCapISO() throws JposException {
068: // the type of cards this reader supports (ISO only)
069: return true;
070: }
071:
072: public boolean getCapJISOne() throws JposException {
073: // the type of cards this reader supports (ISO only)
074: return false;
075: }
076:
077: public boolean getCapJISTwo() throws JposException {
078: // the type of cards this reader supports (ISO only)
079: return false;
080: }
081:
082: public String getAccountNumber() throws JposException {
083: return this .accountNumber[1];
084: }
085:
086: public boolean getAutoDisable() throws JposException {
087: return this .autoDisable;
088: }
089:
090: public void setAutoDisable(boolean b) throws JposException {
091: this .autoDisable = b;
092: }
093:
094: public boolean getDecodeData() throws JposException {
095: return this .decodeData;
096: }
097:
098: public void setDecodeData(boolean b) throws JposException {
099: this .decodeData = b;
100: if (!b) {
101: this .parseDecodeData = false;
102: }
103: }
104:
105: public int getErrorReportingType() throws JposException {
106: return this .errorType;
107: }
108:
109: public void setErrorReportingType(int i) throws JposException {
110: this .errorType = i;
111: }
112:
113: public String getExpirationDate() throws JposException {
114: return this .expireDate[1];
115: }
116:
117: public String getFirstName() throws JposException {
118: return this .firstname;
119: }
120:
121: public String getMiddleInitial() throws JposException {
122: return this .middle;
123: }
124:
125: public boolean getParseDecodeData() throws JposException {
126: return this .parseDecodeData;
127: }
128:
129: public void setParseDecodeData(boolean b) throws JposException {
130: this .parseDecodeData = b;
131: }
132:
133: public String getServiceCode() throws JposException {
134: return this .serviceCode;
135: }
136:
137: public String getSuffix() throws JposException {
138: return this .suffix;
139: }
140:
141: public String getSurname() throws JposException {
142: return this .surname;
143: }
144:
145: public String getTitle() throws JposException {
146: return this .title;
147: }
148:
149: public byte[] getTrack1Data() throws JposException {
150: return this .track1Data;
151: }
152:
153: public byte[] getTrack1DiscretionaryData() throws JposException {
154: return this .track1DiscretionaryData;
155: }
156:
157: public byte[] getTrack2Data() throws JposException {
158: return this .track2Data;
159: }
160:
161: public byte[] getTrack2DiscretionaryData() throws JposException {
162: return this .track2DiscretionaryData;
163: }
164:
165: public byte[] getTrack3Data() throws JposException {
166: return this .track3Data;
167: }
168:
169: public int getTracksToRead() throws JposException {
170: return this .tracksToRead;
171: }
172:
173: public void setTracksToRead(int i) throws JposException {
174: this .tracksToRead = i;
175: }
176:
177: public void clearInput() throws JposException {
178: this .title = null;
179: this .firstname = new String();
180: this .middle = new String();
181: this .surname = new String();
182: this .suffix = new String();
183: this .serviceCode = new String();
184: this .accountNumber = new String[2];
185: this .expireDate = new String[2];
186: this .track1Data = new byte[0];
187: this .track2Data = new byte[0];
188: this .track3Data = new byte[0];
189: this .track1DiscretionaryData = new byte[0];
190: this .track2DiscretionaryData = new byte[0];
191: }
192:
193: // MSRService13
194: public int getCapPowerReporting() throws JposException {
195: return 0; // not used
196: }
197:
198: public int getPowerNotify() throws JposException {
199: return 0; // not used
200: }
201:
202: public void setPowerNotify(int i) throws JposException {
203: // not used
204: }
205:
206: public int getPowerState() throws JposException {
207: return 0; // not used
208: }
209:
210: // MSRService15
211: public boolean getCapTransmitSentinels() throws JposException {
212: return true;
213: }
214:
215: public byte[] getTrack4Data() throws JposException {
216: return new byte[0]; // not implemented
217: }
218:
219: public boolean getTransmitSentinels() throws JposException {
220: return this .sendSentinels;
221: }
222:
223: public void setTransmitSentinels(boolean b) throws JposException {
224: this .sendSentinels = b;
225: }
226:
227: // KeyboardReceiver
228: public synchronized void receiveData(int[] codes, char[] chars) {
229: String data = new String(chars);
230: this .parseMsrString(data);
231:
232: DataEvent event = new DataEvent(this , 0);
233: this .fireEvent(event);
234: }
235:
236: private void parseMsrString(String str) {
237: if (str.indexOf(";") == -1 || str.indexOf("^") == -1) {
238: ErrorEvent error = new ErrorEvent(this ,
239: JposConst.JPOS_E_FAILURE, -1,
240: JposConst.JPOS_EL_INPUT, JposConst.JPOS_ER_CLEAR);
241: this .fireEvent(error);
242: return;
243: }
244:
245: try {
246: // parse the tracks from the character string
247: String track1 = str.substring(0, str.indexOf(";"));
248: String track2 = str.substring(str.indexOf(";"), str
249: .length() - 1);
250:
251: // track 1 data
252: int firstCarrot = track1.indexOf("^", 2);
253: int nextCarrot = track1.indexOf("^", firstCarrot + 1);
254:
255: String tr1BegChar = track1.substring(0, 1);
256: String formatCode = track1.substring(1, 2);
257: String tr1AcctNum = track1.substring(2, firstCarrot);
258: String cardHolder = track1.substring(firstCarrot + 1,
259: nextCarrot);
260: String tr1ExpDate = track1.substring(nextCarrot + 1,
261: nextCarrot + 5);
262: String tr1OptData = track1.substring(nextCarrot + 4, track1
263: .length() - 2);
264: String tr1EndChar = track1.substring(track1.length() - 2,
265: track1.length() - 1);
266: String tr1LrcCode = track1.substring(track1.length() - 1,
267: track1.length());
268:
269: // track 2 data
270: String tr2BegChar = track2.substring(0, 1);
271: String tr2AcctNum = track2
272: .substring(1, track2.indexOf("="));
273: String tr2ExpDate = track2.substring(
274: (track2.indexOf("=") + 1), track2.indexOf("=") + 5);
275: String tr2OptData = track2.substring(
276: track2.indexOf("=") + 5, track2.length() - 2);
277: String tr2EndChar = track2.substring(track2.length() - 2,
278: track2.length() - 1);
279: String tr2LrcCode = track2.substring(track2.length() - 1,
280: track2.length());
281:
282: // see if we need to remove the sentinels
283: if (this .sendSentinels) {
284: track1 = track1.substring(0, track1.length() - 1);
285: track2 = track2.substring(0, track2.length() - 1);
286: } else {
287: track1 = track1.substring(1, track1.length() - 2);
288: track2 = track2.substring(0, track2.length() - 2);
289: }
290:
291: // set the raw track data
292: this .track1Data = track1.getBytes();
293: this .track2Data = track2.getBytes();
294:
295: // parse the decoded data
296: if (this .parseDecodeData) {
297: // set the sentinels
298: this .sentinels = new int[4];
299: this .sentinels[0] = (int) tr1BegChar.charAt(0);
300: this .sentinels[1] = (int) tr1EndChar.charAt(0);
301: this .sentinels[2] = (int) tr2BegChar.charAt(0);
302: this .sentinels[3] = (int) tr2EndChar.charAt(0);
303:
304: // set the lrcs
305: this .lrc = new int[2];
306: this .lrc[0] = (int) tr1LrcCode.charAt(0);
307: this .lrc[1] = (int) tr2LrcCode.charAt(0);
308:
309: // set the account number
310: this .accountNumber = new String[2];
311: this .accountNumber[0] = tr1AcctNum.trim();
312: this .accountNumber[1] = tr2AcctNum.trim();
313:
314: // set the expiration date
315: this .expireDate = new String[2];
316: this .expireDate[0] = tr1ExpDate.trim();
317: this .expireDate[1] = tr2ExpDate.trim();
318:
319: // track discretionar info
320: this .track1DiscretionaryData = tr1OptData.getBytes();
321: this .track2DiscretionaryData = tr2OptData.getBytes();
322: this .track1Data = track1.getBytes();
323: this .track2Data = track2.getBytes();
324:
325: // other field data (i.e. name)
326: this .serviceCode = formatCode.trim();
327: this .surname = (cardHolder.substring(0, cardHolder
328: .indexOf("/"))).trim();
329: this .firstname = (cardHolder.substring((cardHolder
330: .indexOf("/") + 1))).trim();
331: // not sure how to support title, middle initial, and suffix
332: }
333: } catch (Exception e) {
334: ErrorEvent error = new ErrorEvent(this ,
335: JposConst.JPOS_E_FAILURE, -1,
336: JposConst.JPOS_EL_INPUT, JposConst.JPOS_ER_CLEAR);
337: this.fireEvent(error);
338: return;
339: }
340: }
341: }
|