20 | #include "PrintQueue.h"
21 |
22 | typedef enum {
23 | IDLE,
24 | PRINTING_FROM_SERVER,
25 | PRINTING_FROM_QUEUE
26 | } printer_status;
27 |
28 | class Printer {
29 | private:
30 | printer_status status = IDLE;
31 | int printingClientId = 0;
32 | PrintQueue queue;
33 | String name;
34 | protected:
35 | Printer(String _printerId);
36 | // startJob() and endJob() do nothing by default, and can be overriden if a specifica
37 | // type of printer port has specific tasks to do before or after a print job
38 | virtual void startJob();
39 | virtual void endJob();
40 | virtual bool canPrint() = 0;
41 | virtual void printByte(byte b) = 0;
42 | public:
43 | void init();
44 | void startJob(int clientId);
45 | void endJob(int clientId, bool cancel);
46 | bool canPrint(int clientId);
47 | void printByte(int clientId, byte b);
48 | void processQueue();
49 | String getName();
50 | virtual String getInfo() = 0;
51 | };
52 |
--------------------------------------------------------------------------------
/printserver/SerialPortPrinter.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of printserver-esp8266.
3 |
4 | printserver-esp8266 is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | printserver-esp8266 is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with printserver-esp8266. If not, see .
16 | */
17 |
18 | #include "SerialPortPrinter.h"
19 |
20 | SerialPortPrinter::SerialPortPrinter(String _printerId, Stream* s): Printer(_printerId) {
21 | stream = s;
22 | }
23 |
24 | bool SerialPortPrinter::canPrint() {
25 | return true;
26 | }
27 |
28 | void SerialPortPrinter::printByte(byte b) {
29 | stream->write(b);
30 | }
31 |
32 | String SerialPortPrinter::getInfo() {
33 | return "Serial port printer";
34 | }
35 |
--------------------------------------------------------------------------------
/printserver/SerialPortPrinter.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of printserver-esp8266.
3 |
4 | printserver-esp8266 is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | printserver-esp8266 is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with printserver-esp8266. If not, see .
16 | */
17 |
18 | #pragma once
19 | #include "Printer.h"
20 |
21 | class SerialPortPrinter: public Printer {
22 | private:
23 | Stream* stream;
24 | protected:
25 | bool canPrint();
26 | void printByte(byte b);
27 | public:
28 | SerialPortPrinter(String _printerId, Stream* s);
29 | String getInfo();
30 | };
31 |
--------------------------------------------------------------------------------
/printserver/Settings.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of printserver-esp8266.
3 |
4 | printserver-esp8266 is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | printserver-esp8266 is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with printserver-esp8266. If not, see .
16 | */
17 |
18 | #pragma once
19 |
20 | #define MAXCLIENTS 4
21 |
22 | #define JOB_TIMEOUT_MS 4*60*1000
23 | #define NETWORK_READ_TIMEOUT_MS 10*1000
24 |
25 | #define SOCKET_SERVER_PORT 9100
26 | #define IPP_SERVER_PORT 631
27 | #define HTTP_SERVER_PORT 80
28 |
--------------------------------------------------------------------------------
/printserver/ShiftRegParallelPortPrinter.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of printserver-esp8266.
3 |
4 | printserver-esp8266 is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | printserver-esp8266 is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with printserver-esp8266. If not, see .
16 | */
17 |
18 | #include "ShiftRegParallelPortPrinter.h"
19 |
20 | ShiftRegParallelPortPrinter::ShiftRegParallelPortPrinter(String _printerId, int _dataPin, int _clkPin, int _latchPin, int _strobePin, int _busyPin): ParallelPortPrinter(_printerId, _strobePin, _busyPin) {
21 | dataPin = _dataPin;
22 | clkPin = _clkPin;
23 | latchPin = _latchPin;
24 | pinMode(dataPin, OUTPUT);
25 | pinMode(clkPin, OUTPUT);
26 | pinMode(latchPin, OUTPUT);
27 | }
28 |
29 | void ShiftRegParallelPortPrinter::setDataBus(byte b) {
30 | digitalWrite(latchPin, LOW);
31 | shiftOut(dataPin, clkPin, MSBFIRST, b);
32 | digitalWrite(latchPin, HIGH);
33 | }
34 |
--------------------------------------------------------------------------------
/printserver/ShiftRegParallelPortPrinter.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of printserver-esp8266.
3 |
4 | printserver-esp8266 is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | printserver-esp8266 is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with printserver-esp8266. If not, see .
16 | */
17 |
18 | #pragma once
19 | #include "ParallelPortPrinter.h"
20 |
21 | class ShiftRegParallelPortPrinter: public ParallelPortPrinter {
22 | private:
23 | int dataPin;
24 | int clkPin;
25 | int latchPin;
26 | protected:
27 | void setDataBus(byte b);
28 | public:
29 | ShiftRegParallelPortPrinter(String _printerId, int _dataPin, int _clkPin, int _latchPin, int _strobePin, int _busyPin);
30 | };
31 |
--------------------------------------------------------------------------------
/printserver/TcpPrintServer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of printserver-esp8266.
3 |
4 | printserver-esp8266 is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | printserver-esp8266 is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with printserver-esp8266. If not, see .
16 | */
17 |
18 | #include "WiFiManager.h"
19 | #include "Settings.h"
20 | #include "HttpStream.h"
21 | #include "IppStream.h"
22 | #include "TcpPrintServer.h"
23 |
24 | TcpPrintServer::TcpPrintServer(Printer** _printers, int _printerCount) : socketServer(SOCKET_SERVER_PORT), ippServer(IPP_SERVER_PORT), httpServer(HTTP_SERVER_PORT) {
25 | printers = _printers;
26 | printerCount = _printerCount;
27 | for (int i = 0; i < MAXCLIENTS; i++) {
28 | clients[i] = NULL;
29 | }
30 | }
31 |
32 | void TcpPrintServer::handleClient(int index) {
33 | Printer* printer = printers[clientTargetPrinters[index]];
34 | if (clients[index]->hasMoreData()) {
35 | if (clients[index]->dataAvailable() && printer->canPrint(index)) {
36 | printer->printByte(index, clients[index]->read());
37 | }
38 | } else {
39 | Serial.println("Disconnected");
40 | delete clients[index];
41 | clients[index] = NULL;
42 | printer->endJob(index, false);
43 | }
44 | }
45 |
46 | void TcpPrintServer::start() {
47 | socketServer.begin();
48 | ippServer.begin();
49 | httpServer.begin();
50 | }
51 |
52 | int TcpPrintServer::getFreeClientSlot() {
53 | for (int i = 0; i < MAXCLIENTS; i++) {
54 | if (clients[i] == NULL) {
55 | return i;
56 | }
57 | }
58 | return -1;
59 | }
60 |
61 | void TcpPrintServer::processNewSocketClients() {
62 | int freeClientSlot = getFreeClientSlot();
63 | if (freeClientSlot != -1) {
64 | WiFiClient newClient = socketServer.available();
65 | if (newClient) {
66 | Serial.println("Connected: " + newClient.remoteIP().toString() + ":" + newClient.remotePort());
67 | clients[freeClientSlot] = new TcpStream(newClient);
68 | clientTargetPrinters[freeClientSlot] = 0;
69 | printers[0]->startJob(freeClientSlot);
70 | }
71 | }
72 | }
73 |
74 | void TcpPrintServer::processNewIppClients() {
75 | WiFiClient _ippClient = ippServer.available();
76 | if (_ippClient) {
77 | IppStream* ippClient = new IppStream(_ippClient);
78 | int freeClientSlot = getFreeClientSlot();
79 | int targetPrinterIndex = ippClient->parseRequest(printers, printerCount);
80 | if (targetPrinterIndex != -1 && freeClientSlot != -1) {
81 | clients[freeClientSlot] = ippClient;
82 | clientTargetPrinters[freeClientSlot] = targetPrinterIndex;
83 | printers[targetPrinterIndex]->startJob(freeClientSlot);
84 | } else {
85 | delete ippClient;
86 | }
87 | }
88 | }
89 |
90 | void TcpPrintServer::processNewWebClients() {
91 | WiFiClient _httpClient = httpServer.available();
92 | if (!_httpClient) {
93 | return;
94 | }
95 | unsigned long startTime = millis();
96 | HttpStream newHttpClient(_httpClient);
97 | if (!newHttpClient.parseRequestHeader()) {
98 | return;
99 | }
100 | String method = newHttpClient.getRequestMethod();
101 | String path = newHttpClient.getRequestPath();
102 | Serial.printf("request parsed: %s %s\r\n", method.c_str(), path.c_str());
103 | if (method == "GET" && path == "/") {
104 | newHttpClient.print("HTTP/1.1 200 OK \r\n\r\nESP8266 print server
WiFi configuration
Printers");
105 | } else if (method == "GET" && path == "/printerInfo") {
106 | newHttpClient.print("HTTP/1.1 200 OK \r\n\r\nAvailable printers
");
107 | for (int i = 0; i < printerCount; i++) {
108 | String name = printers[i]->getName();
109 | String ip = WiFiManager::getIP();
110 | newHttpClient.print("" + name + "
" + printers[i]->getInfo() + "
Accessible at:
- ipp://" + ip + ":" + String(IPP_SERVER_PORT) + "/" + name + "
");
111 | if (i == 0) {
112 | newHttpClient.print("- socket://" + ip + ":" + SOCKET_SERVER_PORT + "
");
113 | }
114 | newHttpClient.print("
");
115 | }
116 | } else if (method == "GET" && path == "/wifi") {
117 | newHttpClient.print("HTTP/1.1 200 OK \r\n\r\nWiFi configuration
Status: ");
118 | newHttpClient.print(WiFiManager::info());
119 | newHttpClient.print("
");
124 | } else if (method == "POST" && path == "/wifi-connect") {
125 | std::map reqData = newHttpClient.parseUrlencodedRequestBody();
126 | newHttpClient.print("HTTP/1.1 200 OK \r\n\r\nOK
");
127 | newHttpClient.flushSendBuffer();
128 | WiFiManager::connectTo(reqData["SSID"].c_str(), reqData["password"]);
129 | } else {
130 | newHttpClient.print("HTTP/1.1 404 Not Found \r\n\r\nNot found
");
131 | }
132 | Serial.println("HTTP client handled in " + String(millis() - startTime) + "ms");
133 | }
134 |
135 | void TcpPrintServer::process() {
136 | for (int i = 0; i < MAXCLIENTS; i++) {
137 | if (clients[i] != NULL) {
138 | handleClient(i);
139 | }
140 | }
141 | processNewSocketClients();
142 | processNewIppClients();
143 | processNewWebClients();
144 | }
145 |
146 | void TcpPrintServer::printInfo() {
147 | int usedSlots = 0;
148 | for (int i = 0; i < MAXCLIENTS; i++) {
149 | if (clients[i] != NULL) {
150 | usedSlots++;
151 | }
152 | }
153 | Serial.printf("Server slots: %d/%d\n", usedSlots, MAXCLIENTS);
154 | }
155 |
--------------------------------------------------------------------------------
/printserver/TcpPrintServer.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of printserver-esp8266.
3 |
4 | printserver-esp8266 is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | printserver-esp8266 is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with printserver-esp8266. If not, see .
16 | */
17 |
18 | #pragma once
19 | #include
20 | #include
21 | #include
22 | #include