#include #include #include // fuer sleep, read, write #include // fuer cfmakeraw #include #include #include // fuer isprint, tolower #include // fuer timeval #include /* fuer sa_family_t fuer hci.h */ #include #include #include #define _USE_BSD #include #include #include #include #include #include #include //#define DEBUG #ifdef DEBUG #define pause_if_debug(t) sleep(t) #else #define pause_if_debug(t) do {} while (0) #endif static int pipe_fd[2]; static void parent(int argc, char *argv[]) { int ctl; int hci_id; char c = 0; sleep(3); pause_if_debug(5); hci_id = hci_devid("hci0"); if ((ctl = hci_open_dev(hci_id)) < 0) return; ioctl(ctl, HCIDEVDOWN, hci_id); pause_if_debug(1); ioctl(ctl, HCIDEVUP, hci_id); write(pipe_fd[1], &c, 1); wait3(NULL, 0, NULL); ioctl(ctl, HCIDEVUP, hci_id); hci_close_dev(ctl); } static void child(int argc, char *argv[]) { bdaddr_t bdaddr_remote, bdaddr_local; struct sockaddr_rc laddr, raddr; struct rfcomm_dev_req req; struct termios ti; char devname[30]; int sock, addr_len; int ctl, rfcomm = -1; int hci_id; int err; char str[] = "Hello, rfcomm.\n", remote[20]; char c; sleep(1); hci_id = hci_devid("hci0"); sprintf(str, "Hello, rfcomm%.1d\n", hci_id); puts(str); if ((ctl = hci_open_dev(hci_id)) < 0) return; pause_if_debug(1); err = ioctl(ctl, HCIDEVUP, hci_id); pause_if_debug(1); hci_close_dev(ctl); if (err < 0 && errno != EALREADY) return; if (hci_devba(hci_id, &bdaddr_local) < 0) return; pause_if_debug(1); // str2ba(ba_local, &bdaddr_local); laddr.rc_family = AF_BLUETOOTH; bacpy(&laddr.rc_bdaddr, &bdaddr_local); laddr.rc_channel = 0; str2ba(argv[1], &bdaddr_remote); raddr.rc_family = AF_BLUETOOTH; bacpy(&raddr.rc_bdaddr, &bdaddr_remote); // Remote BT-address raddr.rc_channel = 1; // Channel if ((sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) goto out2; pause_if_debug(1); if (bind(sock, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) goto out2; pause_if_debug(1); ba2str(&raddr.rc_bdaddr, remote); printf("connect to %s\n", remote); if (connect(sock, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) { pause_if_debug(2); if ((ctl = hci_open_dev(hci_id)) >= 0) { pause_if_debug(1); ioctl(ctl, HCIDEVDOWN, hci_id); pause_if_debug(1); hci_close_dev(ctl); } printf("%s\n", strerror(errno)); goto out2; } addr_len = sizeof(laddr); if (getsockname(sock, (struct sockaddr *)&laddr, &addr_len) < 0) goto out2; memset(&req, 0, sizeof(req)); req.dev_id = hci_id; req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); bacpy(&req.src, &laddr.rc_bdaddr); bacpy(&req.dst, &raddr.rc_bdaddr); req.channel = raddr.rc_channel; if ((hci_id = ioctl(sock, RFCOMMCREATEDEV, &req)) < 0) goto out2; sprintf(devname, "/dev/rfcomm%d", hci_id); // sleep(2); if ((rfcomm = open(devname, O_RDWR | O_NOCTTY)) < 0) goto out2; // fuer rfcomm-raw-tty-device, ggf. entf. tcflush(rfcomm, TCIOFLUSH); cfmakeraw(&ti); tcsetattr(rfcomm, TCSANOW, &ti); // sleep(2); if (write(rfcomm, str, strlen(str)) < 0) printf("error %s\n", strerror(errno)); out2: read(pipe_fd[0], &c, 1); if (rfcomm > 0) close(rfcomm); close(sock); } int main(int argc, char *argv[]) { int pid; if (pipe(pipe_fd) < 0) exit(1); pid = fork(); if (pid) parent(argc, argv); else child(argc, argv); exit(0); }