1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2003-2009 Marcel Holtmann <marcel (at) holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include <stdio.h> 29 #include <errno.h> 30 #include <unistd.h> 31 #include <signal.h> 32 #include <sys/socket.h> 33 34 #include <bluetooth/bluetooth.h> 35 #include <bluetooth/rfcomm.h> 36 #include <bluetooth/sdp.h> 37 #include <bluetooth/sdp_lib.h> 38 39 #include "cups.h" 40 41 int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class) 42 { 43 struct sockaddr_rc addr; 44 unsigned char buf[2048]; 45 int i, sk, err, len; 46 47 if ((sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { 48 perror("ERROR: Can't create socket"); 49 if (cups_class) 50 return CUPS_BACKEND_FAILED; 51 else 52 return CUPS_BACKEND_RETRY; 53 } 54 55 addr.rc_family = AF_BLUETOOTH; 56 bacpy(&addr.rc_bdaddr, src); 57 addr.rc_channel = 0; 58 59 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 60 perror("ERROR: Can't bind socket"); 61 close(sk); 62 if (cups_class) 63 return CUPS_BACKEND_FAILED; 64 else 65 return CUPS_BACKEND_RETRY; 66 } 67 68 addr.rc_family = AF_BLUETOOTH; 69 bacpy(&addr.rc_bdaddr, dst); 70 addr.rc_channel = channel; 71 72 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 73 perror("ERROR: Can't connect to device"); 74 close(sk); 75 if (cups_class) 76 return CUPS_BACKEND_FAILED; 77 else 78 return CUPS_BACKEND_RETRY; 79 } 80 81 fputs("STATE: -connecting-to-device\n", stderr); 82 83 /* Ignore SIGTERM signals if printing from stdin */ 84 if (fd == 0) { 85 #ifdef HAVE_SIGSET 86 sigset(SIGTERM, SIG_IGN); 87 #elif defined(HAVE_SIGACTION) 88 memset(&action, 0, sizeof(action)); 89 sigemptyset(&action.sa_mask); 90 action.sa_handler = SIG_IGN; 91 sigaction(SIGTERM, &action, NULL); 92 #else 93 signal(SIGTERM, SIG_IGN); 94 #endif /* HAVE_SIGSET */ 95 } 96 97 for (i = 0; i < copies; i++) { 98 99 if (fd != 0) { 100 fprintf(stderr, "PAGE: 1 1\n"); 101 lseek(fd, 0, SEEK_SET); 102 } 103 104 while ((len = read(fd, buf, sizeof(buf))) > 0) { 105 err = write(sk, buf, len); 106 if (err < 0) { 107 perror("ERROR: Error writing to device"); 108 close(sk); 109 return CUPS_BACKEND_FAILED; 110 } 111 } 112 113 } 114 115 close(sk); 116 117 return CUPS_BACKEND_OK; 118 } 119