diff options
| -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;  } | 
