OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 132 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 132 Rev 182
Line 1... Line 1...
1
/*
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 * 
3
 * 
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
4
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
5
 * 
5
 * 
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
9
 * language governing permissions and limitations under the License.
Line 11... Line 11...
11
 * When distributing the software, include this License Header Notice in each file.
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
12
 */
13
 
13
 
14
 package org.openconcerto.erp.core.sales.pos.io;
14
 package org.openconcerto.erp.core.sales.pos.io;
15
 
15
 
16
import gnu.io.CommPort;
-
 
17
import gnu.io.CommPortIdentifier;
16
import org.openconcerto.erp.core.sales.pos.io.ConcertProtocol.ConcertStateListener.States;
18
import gnu.io.SerialPort;
17
import org.openconcerto.utils.StringUtils;
19
 
18
 
20
import java.io.ByteArrayOutputStream;
19
import java.io.ByteArrayOutputStream;
-
 
20
import java.io.FileInputStream;
-
 
21
import java.io.FileOutputStream;
21
import java.io.InputStream;
22
import java.io.InputStream;
22
import java.io.OutputStream;
23
import java.io.OutputStream;
-
 
24
import java.util.ArrayList;
-
 
25
import java.util.List;
23
 
26
 
24
import org.apache.poi.util.HexDump;
27
import org.apache.poi.util.HexDump;
25
 
28
 
-
 
29
import gnu.io.CommPort;
-
 
30
import gnu.io.CommPortIdentifier;
-
 
31
import gnu.io.SerialPort;
-
 
32
 
26
public class ConcertProtocol {
33
public class ConcertProtocol {
-
 
34
 
-
 
35
    public interface ConcertStateListener {
-
 
36
        enum States {
-
 
37
            ERROR, CONNECTED, WAITING, OK, NOK
-
 
38
        }
-
 
39
 
-
 
40
        void stateChanged(States state);
-
 
41
    }
-
 
42
 
27
    // Message start
43
    // Message start
28
    private static final char STX = (char) 0x02;
44
    private static final char STX = (char) 0x02;
29
    // Message end
45
    // Message end
30
    private static final char ETX = (char) 0x03;
46
    private static final char ETX = (char) 0x03;
31
    // End of transmission
47
    // End of transmission
Line 45... Line 61...
45
 
61
 
46
    // Currency
62
    // Currency
47
    public static final String CURRENCY_EUR = "978";
63
    public static final String CURRENCY_EUR = "978";
48
    private String port;
64
    private String port;
49
 
65
 
-
 
66
    private List<ConcertStateListener> listeners = new ArrayList<>();
-
 
67
 
50
    public ConcertProtocol(String port) {
68
    public ConcertProtocol(String port) {
51
        this.port = port;
69
        this.port = port;
52
    }
70
    }
53
 
71
 
-
 
72
    public void addStateListener(ConcertStateListener listener) {
-
 
73
        listeners.add(listener);
-
 
74
    }
-
 
75
 
-
 
76
    private void fireStateChanged(States connected) {
-
 
77
        for (ConcertStateListener l : listeners)
-
 
78
            l.stateChanged(connected);
-
 
79
    }
-
 
80
 
54
    public synchronized boolean sendCardPayment(int amountInCents, String currency) throws Exception {
81
    public synchronized boolean sendCardPayment(int amountInCents, String currency) throws Exception {
55
        if (currency == null) {
82
        if (currency == null) {
56
            currency = CURRENCY_EUR;
83
            currency = CURRENCY_EUR;
57
        }
84
        }
58
        return sendPrototolE(1, amountInCents, true, MODE_CARD, TYPE_BUY, currency, "OpenConcerto");
85
        return sendPrototolE(1, amountInCents, true, MODE_CARD, TYPE_BUY, currency, "OpenConcerto");
59
    }
86
    }
60
 
87
 
61
    public boolean sendPrototolE(int posIndex, int amountInCents, boolean requireResponse, char mode, char type, String currency, String string) throws Exception {
88
    public boolean sendPrototolE(int posIndex, int amountInCents, boolean requireResponse, char mode, char type, String currency, String string) throws Exception {
62
        boolean result = false;
89
        boolean result = false;
63
        if (posIndex > 99 || posIndex < 0) {
90
        if (posIndex > 99 || posIndex < 0) {
-
 
91
            fireStateChanged(ConcertStateListener.States.ERROR);
64
            throw new IllegalArgumentException("Pos index must be between 0 and 99");
92
            throw new IllegalArgumentException("Pos index must be between 0 and 99");
65
        }
93
        }
66
        if (amountInCents < 0) {
94
        if (amountInCents < 0) {
-
 
95
            fireStateChanged(ConcertStateListener.States.ERROR);
67
            throw new IllegalArgumentException("Amount must be positive");
96
            throw new IllegalArgumentException("Amount must be positive");
68
        }
97
        }
69
        if (currency.length() != 3) {
98
        if (currency.length() != 3) {
-
 
99
            fireStateChanged(ConcertStateListener.States.ERROR);
70
            throw new IllegalArgumentException("Bad currency code : " + currency);
100
            throw new IllegalArgumentException("Bad currency code : " + currency);
71
        }
101
        }
72
 
102
 
-
 
103
        final OutputStream out;
-
 
104
        InputStream in;
-
 
105
        final SerialPort serialPort;
-
 
106
        if (isSerialPort()) {
73
        final SerialPort serialPort = getSerialPort();
107
            serialPort = getSerialPort();
74
        final OutputStream out = serialPort.getOutputStream();
108
            out = serialPort.getOutputStream();
75
        final InputStream in = serialPort.getInputStream();
109
            in = serialPort.getInputStream();
-
 
110
        } else {
-
 
111
            serialPort = null;
-
 
112
            in = new FileInputStream(this.port);
-
 
113
 
-
 
114
            if (in.available() > 0) {
-
 
115
                byte[] buffer = new byte[512];
-
 
116
                in.read(buffer);
-
 
117
                in.close();
-
 
118
            }
-
 
119
            in = new FileInputStream(this.port);
-
 
120
            out = new FileOutputStream(this.port);
-
 
121
        }
76
 
122
 
77
        out.write(ENQ);
123
        out.write(ENQ);
78
 
124
 
79
        byte[] buffer = new byte[512];
125
        byte[] buffer = new byte[512];
80
        int nbRead = in.read(buffer);
126
        int nbRead = in.read(buffer);
81
 
127
 
82
        if (nbRead != 1 || buffer[0] != ACK) {
128
        if (nbRead != 1 || buffer[0] != ACK) {
83
            String r = HexDump.toHex(buffer, nbRead);
129
            String r = StringUtils.bytesToHexString(buffer, nbRead);
-
 
130
            in.close();
-
 
131
            out.close();
-
 
132
            if (serialPort != null) {
84
            serialPort.close();
133
                serialPort.close();
-
 
134
            }
-
 
135
            fireStateChanged(ConcertStateListener.States.ERROR);
85
            throw new IllegalStateException("Bad response received : " + r);
136
            throw new IllegalStateException("Bad response received : " + r);
86
        }
137
        }
-
 
138
 
-
 
139
        fireStateChanged(ConcertStateListener.States.CONNECTED);
-
 
140
 
87
        //
141
        //
88
        final ByteArrayOutputStream bOut = new ByteArrayOutputStream();
142
        final ByteArrayOutputStream bOut = new ByteArrayOutputStream();
89
        bOut.write(STX);
143
        bOut.write(STX);
90
        // POS Index
144
        // POS Index
91
        String n = rightAlign(posIndex, 2, '0');
145
        String n = rightAlign(posIndex, 2, '0');
Line 110... Line 164...
110
        out.write(bOut.toByteArray());
164
        out.write(bOut.toByteArray());
111
 
165
 
112
        // READ ACK
166
        // READ ACK
113
        nbRead = in.read(buffer);
167
        nbRead = in.read(buffer);
114
        if (nbRead != 1 || buffer[0] != ACK) {
168
        if (nbRead != 1 || buffer[0] != ACK) {
115
            String r = HexDump.toHex(buffer, nbRead);
169
            String r = StringUtils.bytesToHexString(buffer, nbRead);
-
 
170
            in.close();
-
 
171
            out.close();
-
 
172
            if (serialPort != null) {
116
            serialPort.close();
173
                serialPort.close();
-
 
174
            }
-
 
175
            fireStateChanged(ConcertStateListener.States.ERROR);
117
            throw new IllegalStateException("Bad response received : " + nbRead + ": " + r);
176
            throw new IllegalStateException("Bad response received : " + nbRead + ": " + r);
118
        }
177
        }
119
 
178
 
120
        // END
179
        // END
121
        out.write(EOT);
180
        out.write(EOT);
122
 
181
 
-
 
182
        fireStateChanged(ConcertStateListener.States.WAITING);
-
 
183
 
123
        // Wait reply
184
        // Wait reply
124
        int count = 0;
185
        int count = 0;
125
        final int maxCount = 60 * 5;
186
        final int maxCount = 60 * 5;
126
        while (count < maxCount) {
187
        while (count < maxCount) {
127
            nbRead = in.read(buffer);
188
            nbRead = in.read(buffer);
Line 131... Line 192...
131
                } else if (buffer[0] == STX) {
192
                } else if (buffer[0] == STX) {
132
                    if (buffer[3] == '0') {
193
                    if (buffer[3] == '0') {
133
                        result = true;
194
                        result = true;
134
                        out.write(ACK);
195
                        out.write(ACK);
135
                        count = maxCount;
196
                        count = maxCount;
-
 
197
                        fireStateChanged(ConcertStateListener.States.OK);
136
                    } else if (buffer[3] == '7') {
198
                    } else if (buffer[3] == '7') {
137
                        out.write(NACK);
199
                        out.write(NACK);
138
                        count = maxCount;
200
                        count = maxCount;
-
 
201
                        fireStateChanged(ConcertStateListener.States.NOK);
139
                    }
202
                    }
140
                } else if (buffer[0] == EOT) {
203
                } else if (buffer[0] == EOT) {
141
                    count = maxCount;
204
                    count = maxCount;
142
                }
205
                }
143
            }
206
            }
Line 146... Line 209...
146
 
209
 
147
        }
210
        }
148
 
211
 
149
        out.close();
212
        out.close();
150
        in.close();
213
        in.close();
-
 
214
        if (serialPort != null) {
151
        serialPort.close();
215
            serialPort.close();
-
 
216
        }
-
 
217
 
152
        return result;
218
        return result;
153
    }
219
    }
154
 
220
 
155
    private byte getLrc(byte[] bytes) {
221
    private byte getLrc(byte[] bytes) {
156
        byte LRC = (byte) 0x0;
222
        byte lrc = (byte) 0x0;
157
        for (int i = 1; i < bytes.length; i++) {
223
        for (int i = 1; i < bytes.length; i++) {
158
            LRC ^= bytes[i];
224
            lrc ^= bytes[i];
159
        }
225
        }
160
        return LRC;
226
        return lrc;
-
 
227
    }
-
 
228
 
-
 
229
    private boolean isSerialPort() {
-
 
230
        return (this.port.startsWith("/dev") || this.port.startsWith("COM"));
161
    }
231
    }
162
 
232
 
163
    private SerialPort getSerialPort() throws Exception {
233
    private SerialPort getSerialPort() throws Exception {
164
        if (port == null || port.length() == 0) {
234
        if (port == null || port.length() == 0) {
165
            throw new IllegalStateException("Invalid serial port name: " + port);
235
            throw new IllegalStateException("Invalid serial port name: " + port);