Index: hcrp.c =================================================================== RCS file: /cvsroot/bluez/utils/cups/hcrp.c,v retrieving revision 1.8 diff -u -p -u -p -r1.8 hcrp.c --- hcrp.c 6 Mar 2008 10:46:26 -0000 1.8 +++ hcrp.c 14 Mar 2008 11:40:02 -0000 @@ -37,6 +37,8 @@ #include +#include "main.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 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, const char *cups_class, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies) { struct sockaddr_l2 addr; struct l2cap_options opts; @@ -180,7 +182,10 @@ int hcrp_print(bdaddr_t *src, bdaddr_t * 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 * 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 * 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 * 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 * 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 * 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,7 @@ int hcrp_print(bdaddr_t *src, bdaddr_t * fprintf(stderr, "ERROR: Can't grant initial credits\n"); close(data_sk); close(ctrl_sk); - return 1; + return CUPS_BACKEND_AUTH_REQUIRED; } for (i = 0; i < copies; i++) { @@ -306,7 +329,7 @@ int hcrp_print(bdaddr_t *src, bdaddr_t * perror("ERROR: Error writing to device"); close(data_sk); close(ctrl_sk); - return 1; + return CUPS_BACKEND_FAILED; } if (len != count) @@ -320,5 +343,5 @@ int hcrp_print(bdaddr_t *src, bdaddr_t * close(data_sk); close(ctrl_sk); - return 0; + return CUPS_BACKEND_OK; } Index: main.c =================================================================== RCS file: /cvsroot/bluez/utils/cups/main.c,v retrieving revision 1.9 diff -u -p -u -p -r1.9 main.c --- main.c 6 Mar 2008 10:46:26 -0000 1.9 +++ main.c 14 Mar 2008 11:40:02 -0000 @@ -40,23 +40,15 @@ #include +#include "main.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, const char *cups_class, uint8_t channel, int fd, int copies); +extern int hcrp_print(bdaddr_t *src, bdaddr_t *dst, const char *cups_class, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies); #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,14 @@ 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 cups_class %s service %s fd %d copies %d\n", + argv[0], device, cups_class ? cups_class : "(none)", service, fd, copies); 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 +664,24 @@ 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, cups_class, channel, fd, copies); break; case 2: - err = hcrp_print(BDADDR_ANY, &bdaddr, ctrl_psm, data_psm, fd, copies); + err = hcrp_print(BDADDR_ANY, &bdaddr, cups_class, ctrl_psm, data_psm, fd, copies); break; default: err = CUPS_BACKEND_FAILED; @@ -686,6 +689,16 @@ int main(int argc, char *argv[]) break; } + if (err && 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); Index: spp.c =================================================================== RCS file: /cvsroot/bluez/utils/cups/spp.c,v retrieving revision 1.6 diff -u -p -u -p -r1.6 spp.c --- spp.c 6 Mar 2008 10:46:26 -0000 1.6 +++ spp.c 14 Mar 2008 11:40:02 -0000 @@ -34,7 +34,9 @@ #include #include -int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) +#include "main.h" + +int spp_print(bdaddr_t *src, bdaddr_t *dst, const char *cups_class, uint8_t channel, int fd, int copies) { struct sockaddr_rc addr; unsigned char buf[2048]; @@ -42,7 +44,10 @@ int spp_print(bdaddr_t *src, bdaddr_t *d 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 *d 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 *d 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 *d 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 *d close(sk); - return 0; + return CUPS_BACKEND_OK; } --- /dev/null 2008-03-04 15:30:16.223009046 +0000 +++ main.h 2008-03-14 11:26:56.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2008 Marcel Holtmann + * + * + * 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 */ +}; + +/* Extra error status to check whether we should retry sending the document */ +#define CUPS_BACKEND_RETRY CUPS_BACKEND_CANCEL + 1 +