diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-03-14 14:21:01 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-03-14 14:21:01 +0000 |
commit | a71ed7ebdf0599e0a019c9087669a62e026109a2 (patch) | |
tree | a805fba870d310e6ea3e09746757f91d68379bbe /cups | |
parent | 2168a48f8f05562fcd51f17744ead7d1c48e910f (diff) |
Add CLASS support and retry on unavailable printers
Diffstat (limited to 'cups')
-rw-r--r-- | cups/Makefile.am | 2 | ||||
-rw-r--r-- | cups/cups.h | 32 | ||||
-rw-r--r-- | cups/hcrp.c | 48 | ||||
-rw-r--r-- | cups/main.c | 50 | ||||
-rw-r--r-- | cups/spp.c | 23 |
5 files changed, 120 insertions, 35 deletions
diff --git a/cups/Makefile.am b/cups/Makefile.am index 8cd3d4d4..853c436d 100644 --- a/cups/Makefile.am +++ b/cups/Makefile.am @@ -4,7 +4,7 @@ cupsdir = $(libdir)/cups/backend cups_PROGRAMS = bluetooth -bluetooth_SOURCES = main.c sdp.c spp.c hcrp.c +bluetooth_SOURCES = main.c cups.h sdp.c spp.c hcrp.c bluetooth_LDADD = $(top_builddir)/common/libhelper.a \ @DBUS_LIBS@ @GLIB_LIBS@ @BLUEZ_LIBS@ diff --git a/cups/cups.h b/cups/cups.h new file mode 100644 index 00000000..c8de4ab8 --- /dev/null +++ b/cups/cups.h @@ -0,0 +1,32 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2008 Marcel Holtmann <marcel@holtmann.org> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +enum { /**** Backend exit codes ****/ + CUPS_BACKEND_OK = 0, /* Job completed successfully */ + CUPS_BACKEND_FAILED = 1, /* Job failed, use error-policy */ + CUPS_BACKEND_AUTH_REQUIRED = 2, /* Job failed, authentication required */ + CUPS_BACKEND_HOLD = 3, /* Job failed, hold job */ + CUPS_BACKEND_STOP = 4, /* Job failed, stop queue */ + CUPS_BACKEND_CANCEL = 5, /* Job failed, cancel job */ + CUPS_BACKEND_RETRY = 6, /* Failure requires us to retry (BlueZ specific) */ +}; diff --git a/cups/hcrp.c b/cups/hcrp.c index 468e89fb..5f0211e2 100644 --- a/cups/hcrp.c +++ b/cups/hcrp.c @@ -37,6 +37,8 @@ #include <netinet/in.h> +#include "cups.h" + #define HCRP_PDU_CREDIT_GRANT 0x0001 #define HCRP_PDU_CREDIT_REQUEST 0x0002 #define HCRP_PDU_GET_LPT_STATUS 0x0005 @@ -167,7 +169,7 @@ static inline int hcrp_get_next_tid(int tid) return tid + 1; } -int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies) +int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies, const char *cups_class) { struct sockaddr_l2 addr; struct l2cap_options opts; @@ -180,7 +182,10 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s if ((ctrl_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { perror("ERROR: Can't create socket"); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } memset(&addr, 0, sizeof(addr)); @@ -190,7 +195,10 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s if (bind(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("ERROR: Can't bind socket"); close(ctrl_sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } memset(&addr, 0, sizeof(addr)); @@ -201,13 +209,19 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s if (connect(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("ERROR: Can't connect to device"); close(ctrl_sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } if ((data_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { perror("ERROR: Can't create socket"); close(ctrl_sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } memset(&addr, 0, sizeof(addr)); @@ -218,7 +232,10 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s perror("ERROR: Can't bind socket"); close(data_sk); close(ctrl_sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } memset(&addr, 0, sizeof(addr)); @@ -230,7 +247,10 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s perror("ERROR: Can't connect to device"); close(data_sk); close(ctrl_sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } fputs("STATE: -connecting-to-device\n", stderr); @@ -242,7 +262,10 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s perror("ERROR: Can't get socket options"); close(data_sk); close(ctrl_sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } mtu = opts.omtu; @@ -266,7 +289,10 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s fprintf(stderr, "ERROR: Can't grant initial credits\n"); close(data_sk); close(ctrl_sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } for (i = 0; i < copies; i++) { @@ -306,7 +332,7 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s perror("ERROR: Error writing to device"); close(data_sk); close(ctrl_sk); - return 1; + return CUPS_BACKEND_FAILED; } if (len != count) @@ -320,5 +346,5 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s close(data_sk); close(ctrl_sk); - return 0; + return CUPS_BACKEND_OK; } diff --git a/cups/main.c b/cups/main.c index 629295b4..ac77e85d 100644 --- a/cups/main.c +++ b/cups/main.c @@ -40,23 +40,15 @@ #include <glib.h> +#include "cups.h" #include "dbus.h" #include "sdp-xml.h" -enum { /**** Backend exit codes ****/ - CUPS_BACKEND_OK = 0, /* Job completed successfully */ - CUPS_BACKEND_FAILED = 1, /* Job failed, use error-policy */ - CUPS_BACKEND_AUTH_REQUIRED = 2, /* Job failed, authentication required */ - CUPS_BACKEND_HOLD = 3, /* Job failed, hold job */ - CUPS_BACKEND_STOP = 4, /* Job failed, stop queue */ - CUPS_BACKEND_CANCEL = 5 /* Job failed, cancel job */ -}; - extern int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel); extern int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm); -extern int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies); -extern int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies); +extern int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class); +extern int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies, const char *cups_class); #define PRINTER_SERVICE_CLASS_NAME "printer" @@ -563,7 +555,7 @@ int main(int argc, char *argv[]) unsigned short ctrl_psm, data_psm; uint8_t channel, b[6]; char *ptr, str[3], device[18], service[12]; - const char *uri; + const char *uri, *cups_class; int i, err, fd, copies, proto; /* Make sure status messages are not buffered */ @@ -638,11 +630,15 @@ int main(int argc, char *argv[]) proto = 0; } - fprintf(stderr, "DEBUG: %s device %s service %s fd %d copies %d\n", - argv[0], device, service, fd, copies); + cups_class = getenv("CLASS"); + + fprintf(stderr, "DEBUG: %s device %s service %s fd %d copies %d class %s\n", + argv[0], device, service, fd, copies, + cups_class ? cups_class : "(none)"); fputs("STATE: +connecting-to-device\n", stderr); +service_search: sdp = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY); if (!sdp) { fprintf(stderr, "ERROR: Can't open Bluetooth connection\n"); @@ -669,16 +665,26 @@ int main(int argc, char *argv[]) sdp_close(sdp); if (err) { + if (cups_class) { + fputs("INFO: Unable to contact printer, queuing on " + "next printer in class...\n", stderr); + sleep(5); + return CUPS_BACKEND_FAILED; + } + sleep(20); fprintf(stderr, "ERROR: Can't get service information\n"); - return CUPS_BACKEND_FAILED; + goto service_search; } +connect: switch (proto) { case 1: - err = spp_print(BDADDR_ANY, &bdaddr, channel, fd, copies); + err = spp_print(BDADDR_ANY, &bdaddr, channel, + fd, copies, cups_class); break; case 2: - err = hcrp_print(BDADDR_ANY, &bdaddr, ctrl_psm, data_psm, fd, copies); + err = hcrp_print(BDADDR_ANY, &bdaddr, ctrl_psm, data_psm, + fd, copies, cups_class); break; default: err = CUPS_BACKEND_FAILED; @@ -686,6 +692,16 @@ int main(int argc, char *argv[]) break; } + if (err == CUPS_BACKEND_FAILED && cups_class) { + fputs("INFO: Unable to contact printer, queuing on " + "next printer in class...\n", stderr); + sleep(5); + return CUPS_BACKEND_FAILED; + } else if (err == CUPS_BACKEND_RETRY) { + sleep(20); + goto connect; + } + if (fd != 0) close(fd); @@ -34,7 +34,9 @@ #include <bluetooth/bluetooth.h> #include <bluetooth/rfcomm.h> -int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) +#include "cups.h" + +int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class) { struct sockaddr_rc addr; unsigned char buf[2048]; @@ -42,7 +44,10 @@ int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) if ((sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { perror("ERROR: Can't create socket"); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } addr.rc_family = AF_BLUETOOTH; @@ -52,7 +57,10 @@ int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("ERROR: Can't bind socket"); close(sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } addr.rc_family = AF_BLUETOOTH; @@ -62,7 +70,10 @@ int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("ERROR: Can't connect to device"); close(sk); - return 1; + if (cups_class) + return CUPS_BACKEND_FAILED; + else + return CUPS_BACKEND_RETRY; } fputs("STATE: -connecting-to-device\n", stderr); @@ -93,7 +104,7 @@ int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) if (err < 0) { perror("ERROR: Error writing to device"); close(sk); - return 1; + return CUPS_BACKEND_FAILED; } } @@ -101,5 +112,5 @@ int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) close(sk); - return 0; + return CUPS_BACKEND_OK; } |