package com.zywell.cloudtest; import java.io.*; import java.net.*; import java.util.Arrays; public class CloudPrintJavaDockingSampleCode implements Runnable { private ServerSocket serverSocket; private boolean running = true; private final int PORT = 9001; // Command definitions private final byte[] CMD = {0x1F, 0x1B, 0x10, 0x55, 0x02, 0x00}; private final byte[] LOST_CMD = {0x1D, 0x28, 0x48, 0x06, 0x00, 0x30, 0x30, 0x31, 0x32, 0x33, 0x34}; private final byte[] DATA = {}; // Printer status information private PrinterStatusInfo printerStatusInfo = new PrinterStatusInfo(); public static void main(String[] args) { new CloudPrintJavaDockingSampleCode().start(); } public void start() { try { serverSocket = new ServerSocket(PORT); System.out.println("Printer service started, listening on port: " + PORT); while (running) { Socket clientSocket = serverSocket.accept(); System.out.println("New client connected: " + clientSocket.getInetAddress()); // Create a new thread for each client connection new Thread(new ClientHandler(clientSocket)).start(); } } catch (IOException e) { System.err.println("Server exception: " + e.getMessage()); } finally { stop(); } } public void stop() { running = false; try { if (serverSocket != null && !serverSocket.isClosed()) { serverSocket.close(); } } catch (IOException e) { System.err.println("Error while closing server: " + e.getMessage()); } System.out.println("Printer service stopped"); } @Override public void run() { } // Client connection handler class private class ClientHandler implements Runnable { private Socket socket; private DataInputStream in; private DataOutputStream out; private byte[] buffer = new byte[64]; public ClientHandler(Socket socket) { this.socket = socket; } @Override public void run() { try { // Create data input/output streams in = new DataInputStream(socket.getInputStream()); out = new DataOutputStream(socket.getOutputStream()); socket.setSoTimeout(30000); // Set 30-second timeout while (running) { Arrays.fill(buffer, (byte)0); // Clear buffer try { in.read(buffer); // Read data } catch (SocketTimeoutException e) { System.out.println("Socket timeout - closing connection"); return; } catch (IOException e) { System.out.println("IO exception - handling connection reset"); return; } printerStatusInfo.setDefaultStatus(); // Reset status // Device access command processing if (buffer[0] == 0x1F && buffer[1] == 0x1B && buffer[2] == 0x10 && buffer[3] == 0x55) { // Device verification command if (buffer[4] == 0x01 && buffer[5] == 0x02) { byte[] deviceIdByte = Arrays.copyOfRange(buffer, 15, 27); String deviceId = new String(deviceIdByte, "UTF-8"); out.write(LOST_CMD); continue; } // Standby status command if (buffer[4] == 0x02 && buffer[5] == 0x00) { System.out.println("\n===== Printer standby normal ====="); out.write(LOST_CMD); out.write(CMD); continue; } // Printer status exception command if (buffer[4] == 0x03) { System.out.println("\n===== Printer status report ====="); // Process various status bits and output status information boolean havePaper = (buffer[5] & 0x01) == 0; printerStatusInfo.setHavePaper(havePaper); System.out.println("Paper status: " + (havePaper ? "Paper available" : "Out of paper")); boolean coverOpen = (buffer[5] >> 1 & 0x01) == 1; printerStatusInfo.setCoverOpen(coverOpen); System.out.println("Cover status: " + (coverOpen ? "Open" : "Closed")); boolean cutterNormal = (buffer[5] >> 2 & 0x01) == 0; printerStatusInfo.setCutterNormal(cutterNormal); System.out.println("Cutter status: " + (cutterNormal ? "Normal" : "Abnormal")); boolean online = (buffer[5] >> 3 & 0x01) == 0; printerStatusInfo.setOnline(online); System.out.println("Online status: " + (online ? "Online" : "Offline")); boolean feedPaperByBtn = (buffer[5] >> 4 & 0x01) == 1; printerStatusInfo.setFeedPaperByBtn(feedPaperByBtn); System.out.println("Button feed: " + (feedPaperByBtn ? "In progress" : "Not operating")); boolean bufferFull = (buffer[5] >> 5 & 0x01) == 1; printerStatusInfo.setBufferFull(bufferFull); System.out.println("Buffer: " + (bufferFull ? "Full" : "Not full")); // Output overall status evaluation boolean isNormal = printerStatusInfo.isNormalStatus(); System.out.println("Overall status: " + (isNormal ? "Normal" : "Abnormal")); System.out.println("=========================\n"); out.write(LOST_CMD); continue; } // Printer double-click button notification if (buffer[4] == 0x04 && buffer[5] == 0x00) { out.write(DATA); // Print cached last receipt content continue; } } } } catch (IOException e) { e.printStackTrace(); } finally { closeConnection(); } } private void closeConnection() { try { if (in != null) in.close(); if (out != null) out.close(); if (socket != null && !socket.isClosed()) { socket.close(); } } catch (IOException e) { System.err.println("Error while closing connection: " + e.getMessage()); } } } // Printer status information class private static class PrinterStatusInfo { private boolean havePaper; private boolean coverOpen; private boolean cutterNormal; private boolean online; private boolean bufferFull; private boolean feedPaperByBtn; public void setDefaultStatus() { havePaper = false; coverOpen = false; cutterNormal = false; online = false; bufferFull = false; feedPaperByBtn = false; } public boolean isNormalStatus() { return havePaper && !coverOpen && cutterNormal && online && !bufferFull && !feedPaperByBtn; } // Various setter methods public void setHavePaper(boolean havePaper) { this.havePaper = havePaper; } public void setCoverOpen(boolean coverOpen) { this.coverOpen = coverOpen; } public void setCutterNormal(boolean cutterNormal) { this.cutterNormal = cutterNormal; } public void setOnline(boolean online) { this.online = online; } public void setBufferFull(boolean bufferFull) { this.bufferFull = bufferFull; } public void setFeedPaperByBtn(boolean feedPaperByBtn) { this.feedPaperByBtn = feedPaperByBtn; } } }