static int hwftdi_init(void) { int flags; int pipe_rx2main[2] = { -1, -1 }; unsigned char buf[1]; char* p; logprintf(LIRC_INFO, "Initializing FTDI: %s", drv.device); /* Parse the device string, which has the form key=value, * key=value, ... This isn't very nice, but it's not a lot * more complicated than what some of the other drivers do. */ p = device_config = strdup(drv.device); while (p) { char* comma; char* value; comma = strchr(p, ','); if (comma != NULL) *comma = '\0'; /* Skip empty options. */ if (*p == '\0') goto next; value = strchr(p, '='); if (value == NULL) { logprintf(LIRC_ERROR, "device configuration option must contain an '=': '%s'", p); goto fail_start; } *value++ = '\0'; if (strcmp(p, "vendor") == 0) { usb_vendor = strtol(value, NULL, 0); } else if (strcmp(p, "product") == 0) { usb_product = strtol(value, NULL, 0); } else if (strcmp(p, "desc") == 0) { usb_desc = value; } else if (strcmp(p, "serial") == 0) { usb_serial = value; } else if (strcmp(p, "input") == 0) { input_pin = strtol(value, NULL, 0); } else if (strcmp(p, "baud") == 0) { rx_baud_rate = strtol(value, NULL, 0); } else if (strcmp(p, "output") == 0) { output_pin = strtol(value, NULL, 0); } else if (strcmp(p, "txbaud") == 0) { tx_baud_rate = strtol(value, NULL, 0); } else { logprintf(LIRC_ERROR, "unrecognised device configuration option: '%s'", p); goto fail_start; } next: if (comma == NULL) break; p = comma + 1; } rec_buffer_init(); /* Allocate a pipe for lircd to read from */ if (pipe(pipe_rx2main) == -1) { logprintf(LIRC_ERROR, "unable to create pipe_rx2main"); goto fail_start; } if (pipe(pipe_main2tx) == -1) { logprintf(LIRC_ERROR, "unable to create pipe_main2tx"); goto fail_main2tx; } if (pipe(pipe_tx2main) == -1) { logprintf(LIRC_ERROR, "unable to create pipe_tx2main"); goto fail_tx2main; } drv.fd = pipe_rx2main[0]; flags = fcntl(drv.fd, F_GETFL); /* make the read end of the pipe non-blocking: */ if (fcntl(drv.fd, F_SETFL, flags | O_NONBLOCK) == -1) { logprintf(LIRC_ERROR, "unable to make pipe read end non-blocking"); goto fail; } /* Make the read end of the send pipe non-blocking */ flags = fcntl(pipe_main2tx[0], F_GETFL); if (fcntl(pipe_main2tx[0], F_SETFL, flags | O_NONBLOCK) == -1) { logprintf(LIRC_ERROR, "unable to make pipe read end non-blocking"); goto fail; } /* Spawn the child process */ child_pid = fork(); if (child_pid == -1) { logprintf(LIRC_ERROR, "unable to fork child process"); goto fail; } else if (child_pid == 0) { /* we're the child: */ close(pipe_rx2main[0]); close(pipe_main2tx[1]); close(pipe_tx2main[0]); child_process(pipe_rx2main[1], pipe_main2tx[0], pipe_tx2main[1]); } /* we're the parent: */ close(pipe_rx2main[1]); close(pipe_main2tx[0]); pipe_main2tx[0] = -1; close(pipe_tx2main[1]); pipe_tx2main[1] = -1; /* wait for child to be started */ chk_read(pipe_tx2main[0], &buf, 1); return 1; fail: drv.fd = -1; close(pipe_tx2main[0]); close(pipe_tx2main[1]); pipe_tx2main[0] = -1; pipe_tx2main[1] = -1; fail_tx2main: close(pipe_main2tx[0]); close(pipe_main2tx[1]); pipe_main2tx[0] = -1; pipe_main2tx[1] = -1; fail_main2tx: close(pipe_rx2main[0]); close(pipe_rx2main[1]); fail_start: if (device_config != NULL) { free(device_config); device_config = NULL; } return 0; }
static int uirt2_raw_init(void) { int version; if (!tty_create_lock(drv.device)) { log_error("uirt2_raw: could not create lock files"); return 0; } drv.fd = open(drv.device, O_RDWR | O_NONBLOCK | O_NOCTTY); if (drv.fd < 0) { log_error("uirt2_raw: could not open %s", drv.device); tty_delete_lock(); return 0; } if (!tty_reset(drv.fd)) { log_error("uirt2_raw: could not reset tty"); close(drv.fd); tty_delete_lock(); return 0; } /* Wait for UIRT device to power up */ usleep(100 * 1000); if (!tty_setbaud(drv.fd, 115200)) { log_error("uirt2_raw: could not set baud rate"); close(drv.fd); tty_delete_lock(); return 0; } if (!tty_setcsize(drv.fd, 8)) { log_error("uirt2_raw: could not set csize"); close(drv.fd); tty_delete_lock(); return 0; } if (!tty_setrtscts(drv.fd, 1)) { log_error("uirt2_raw: could not enable hardware flow"); close(drv.fd); tty_delete_lock(); return 0; } dev = uirt2_init(drv.fd); if (dev == NULL) { log_error("uirt2_raw: No UIRT2 device found at %s", drv.device); close(drv.fd); tty_delete_lock(); return 0; } if (uirt2_setmoderaw(dev) < 0) { log_error("uirt2_raw: could not set raw mode"); uirt2_raw_deinit(); return 0; } if (uirt2_getversion(dev, &version) < 0) { uirt2_raw_deinit(); return 0; } if (version >= 0x0905) { if (!tty_setdtr(drv.fd, 0)) { log_error("uirt2_raw: could not set DTR"); uirt2_raw_deinit(); return 0; } } rec_buffer_init(); send_buffer_init(); rec_rptr = 0; rec_wptr = 0; rec_size = sizeof(rec_buf) / sizeof(rec_buf[0]); return 1; }
/* * interface functions */ int default_init(void) { struct stat s; int i; /* FIXME: other modules might need this, too */ rec_buffer_init(); send_buffer_init(); if (set_rc_protocol(drv.device) != 0) log_info("Cannot configure the rc device for %s", drv.device); if (stat(drv.device, &s) == -1) { log_error("could not get file information for %s", drv.device); log_perror_err("default_init()"); return 0; } /* file could be unix socket, fifo and native lirc device */ if (S_ISSOCK(s.st_mode)) { struct sockaddr_un addr; addr.sun_family = AF_UNIX; strncpy(addr.sun_path, drv.device, sizeof(addr.sun_path) - 1); drv.fd = socket(AF_UNIX, SOCK_STREAM, 0); if (drv.fd == -1) { log_error("could not create socket"); log_perror_err("default_init()"); return 0; } if (connect(drv.fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { log_error("could not connect to unix socket %s", drv.device); log_perror_err("default_init()"); default_deinit(); close(drv.fd); return 0; } log_trace("using unix socket lirc device"); drv.features = LIRC_CAN_REC_MODE2 | LIRC_CAN_SEND_PULSE; drv.rec_mode = LIRC_MODE_MODE2; /* this might change in future */ drv.send_mode = LIRC_MODE_PULSE; return 1; } drv.fd = open(drv.device, O_RDWR); if (drv.fd < 0) { log_error("could not open %s", drv.device); log_perror_err("default_init()"); return 0; } if (S_ISFIFO(s.st_mode)) { log_trace("using defaults for the Irman"); drv.features = LIRC_CAN_REC_MODE2; drv.rec_mode = LIRC_MODE_MODE2; /* this might change in future */ return 1; } else if (!S_ISCHR(s.st_mode)) { default_deinit(); log_error("%s is not a character device!!!", drv.device); log_perror_err("something went wrong during installation"); return 0; } else if (default_ioctl(LIRC_GET_FEATURES, &drv.features) == -1) { log_error("could not get hardware features"); log_error("this device driver does not support the LIRC ioctl interface"); if (major(s.st_rdev) == 13) { log_error("did you mean to use the devinput driver instead of the %s driver?", drv.name); } else { log_error("major number of %s is %lu", drv.device, (__u32)major(s.st_rdev)); log_error("make sure %s is a LIRC device and use a current version of the driver", drv.device); } default_deinit(); return 0; } if (!(LIRC_CAN_SEND(drv.features) || LIRC_CAN_REC(drv.features))) log_trace("driver supports neither sending nor receiving of IR signals"); if (LIRC_CAN_SEND(drv.features) && LIRC_CAN_REC(drv.features)) { log_trace("driver supports both sending and receiving"); } else if (LIRC_CAN_SEND(drv.features)) { log_trace("driver supports sending"); } else if (LIRC_CAN_REC(drv.features)) { log_trace("driver supports receiving"); } /* set send/receive method */ drv.send_mode = 0; if (LIRC_CAN_SEND(drv.features)) { for (i = 0; supported_send_modes[i] != 0; i++) { if (LIRC_CAN_SEND(drv.features) == supported_send_modes[i]) { drv.send_mode = LIRC_SEND2MODE(supported_send_modes[i]); break; } } if (supported_send_modes[i] == 0) log_notice("the send method of the driver is not yet supported by lircd"); } drv.rec_mode = 0; if (LIRC_CAN_REC(drv.features)) { for (i = 0; supported_rec_modes[i] != 0; i++) { if (LIRC_CAN_REC(drv.features) == supported_rec_modes[i]) { drv.rec_mode = LIRC_REC2MODE(supported_rec_modes[i]); break; } } if (supported_rec_modes[i] == 0) log_notice("the receive method of the driver is not yet supported by lircd"); } if (drv.rec_mode == LIRC_MODE_MODE2) { /* get resolution */ drv.resolution = 0; if ((drv.features & LIRC_CAN_GET_REC_RESOLUTION) && (default_ioctl(LIRC_GET_REC_RESOLUTION, &drv.resolution) != -1)) log_trace("resolution of receiver: %d", drv.resolution); } else if (drv.rec_mode == LIRC_MODE_LIRCCODE) { if (default_ioctl(LIRC_GET_LENGTH, (void*)&drv.code_length) == -1) { log_error("could not get code length"); log_perror_err("default_init()"); default_deinit(); return 0; } if (drv.code_length > sizeof(ir_code) * CHAR_BIT) { log_error("lircd can not handle %lu bit codes", drv.code_length); default_deinit(); return 0; } } if (!(drv.send_mode || drv.rec_mode)) { default_deinit(); return 0; } return 1; }
/* initialize driver -- returns 1 on success, 0 on error */ static int ati_init(void) { struct usb_device* usb_dev; int pipe_fd[2] = { -1, -1 }; LOGPRINTF(1, "initializing USB receiver"); rec_buffer_init(); /* A separate process will be forked to read data from the USB * receiver and write it to a pipe. drv.fd is set to the readable * end of this pipe. */ if (pipe(pipe_fd) != 0) { logperror(LIRC_ERROR, "couldn't open pipe"); return 0; } drv.fd = pipe_fd[0]; usb_dev = find_usb_device(); if (usb_dev == NULL) { logprintf(LIRC_ERROR, "couldn't find a compatible USB device"); return 0; } if (!find_device_endpoints(usb_dev)) { logprintf(LIRC_ERROR, "couldn't find device endpoints"); return 0; } dev_handle = usb_open(usb_dev); if (dev_handle == NULL) { logperror(LIRC_ERROR, "couldn't open USB receiver"); goto fail; } if (usb_claim_interface(dev_handle, 0) != 0) { logperror(LIRC_ERROR, "couldn't claim USB interface"); goto fail; } errno = 0; if ((usb_interrupt_write(dev_handle, dev_ep_out->bEndpointAddress, init1, sizeof(init1), 100) != sizeof(init1)) || (usb_interrupt_write(dev_handle, dev_ep_out->bEndpointAddress, init2, sizeof(init2), 100) != sizeof(init2))) { logprintf(LIRC_ERROR, "couldn't initialize USB receiver: %s", errno ? strerror(errno) : "short write"); goto fail; } snprintf(device_path, sizeof(device_path), "/dev/bus/usb/%s/%s", usb_dev->bus->dirname, usb_dev->filename); drv.device = device_path; logprintf(LIRC_DEBUG, "atilibusb: using device: %s", device_path); child = fork(); if (child == -1) { logperror(LIRC_ERROR, "couldn't fork child process"); goto fail; } else if (child == 0) { usb_read_loop(pipe_fd[1]); } return 1; fail: if (dev_handle) { usb_close(dev_handle); dev_handle = NULL; } if (pipe_fd[0] >= 0) close(pipe_fd[0]); if (pipe_fd[1] >= 0) close(pipe_fd[1]); return 0; }