static gboolean uart_event(GIOChannel *channel, GIOCondition cond, gpointer data) { int uart_fd, ldisc; DBG(""); uart_fd = g_io_channel_unix_get_fd(channel); if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { connman_error("UART event 0x%x", cond); if (uart_watch > 0) g_source_remove(uart_watch); goto err; } if (read_command_complete(uart_fd, HCI_HDR_OPCODE) < 0) goto err; if (set_custom_baud_rate(uart_fd, baud_rate, 1) < 0) goto err; ldisc = N_TI_WL; if (ioctl(uart_fd, TIOCSETD, &ldisc) < 0) goto err; g_atomic_int_set(&install_count, 0); return FALSE; err: g_atomic_int_set(&install_count, 0); g_io_channel_shutdown(channel, TRUE, NULL); g_io_channel_unref(channel); return FALSE; }
/* Function to configure the UART * on receiving a notification from the ST KIM driver to install the line * discipline, this function does UART configuration necessary for the STK */ int st_uart_config(unsigned char install) { int ldisc, len, fd, flow_ctrl; unsigned char buf[UART_DEV_NAME_LEN]; uim_speed_change_cmd cmd; char uart_dev_name[UART_DEV_NAME_LEN]; long cust_baud_rate; uim_bdaddr_change_cmd addr_cmd; UIM_START_FUNC(); if (install == '1') { memset(buf, 0, UART_DEV_NAME_LEN); fd = open(DEV_NAME_SYSFS, O_RDONLY); if (fd < 0) { UIM_ERR("Can't open %s", DEV_NAME_SYSFS); return -1; } len = read(fd, buf, UART_DEV_NAME_LEN); if (len < 0) { UIM_ERR("read err (%s)", strerror(errno)); close(fd); return len; } sscanf((const char*)buf, "%s", uart_dev_name); close(fd); memset(buf, 0, UART_DEV_NAME_LEN); fd = open(BAUD_RATE_SYSFS, O_RDONLY); if (fd < 0) { UIM_ERR("Can't open %s", BAUD_RATE_SYSFS); return -1; } len = read(fd, buf, UART_DEV_NAME_LEN); if (len < 0) { UIM_ERR("read err (%s)", strerror(errno)); close(fd); return len; } close(fd); sscanf((const char*)buf, "%ld", &cust_baud_rate); memset(buf, 0, UART_DEV_NAME_LEN); fd = open(FLOW_CTRL_SYSFS, O_RDONLY); if (fd < 0) { UIM_ERR("Can't open %s", FLOW_CTRL_SYSFS); close(fd); return -1; } len = read(fd, buf, UART_DEV_NAME_LEN); if (len < 0) { UIM_ERR("read err (%s)", strerror(errno)); close(fd); return len; } close(fd); sscanf((const char*)buf, "%d", &flow_ctrl); UIM_VER(" signal received, opening %s", uart_dev_name); dev_fd = open(uart_dev_name, O_RDWR); if (dev_fd < 0) { UIM_ERR("Can't open %s", uart_dev_name); return -1; } /* * Set only the default baud rate. * This will set the baud rate to default 115200 */ if (set_baud_rate(dev_fd) < 0) { UIM_ERR("set_baudrate() failed"); close(dev_fd); return -1; } fcntl(dev_fd, F_SETFL,fcntl(dev_fd, F_GETFL) | O_NONBLOCK); /* Set only the custom baud rate */ if (cust_baud_rate != 115200) { UIM_VER("Setting speed to %ld", cust_baud_rate); /* Forming the packet for Change speed command */ cmd.uart_prefix = HCI_COMMAND_PKT; cmd.hci_hdr.opcode = HCI_HDR_OPCODE; cmd.hci_hdr.plen = sizeof(unsigned long); cmd.speed = cust_baud_rate; /* Writing the change speed command to the UART * This will change the UART speed at the controller * side */ len = write(dev_fd, &cmd, sizeof(cmd)); if (len < 0) { UIM_ERR("Failed to write speed-set command"); close(dev_fd); return -1; } /* Read the response for the Change speed command */ if (read_command_complete(dev_fd, HCI_HDR_OPCODE) < 0) { close(dev_fd); return -1; } UIM_VER("Speed changing to %ld, %d", cust_baud_rate, flow_ctrl); /* Set the actual custom baud rate at the host side */ if (set_custom_baud_rate(dev_fd, cust_baud_rate, flow_ctrl) < 0) { UIM_ERR("set_custom_baud_rate() failed"); close(dev_fd); return -1; } /* Set the uim BD address */ if (uim_bd_address[0] != 0) { memset(&addr_cmd, 0, sizeof(addr_cmd)); /* Forming the packet for change BD address command*/ addr_cmd.uart_prefix = HCI_COMMAND_PKT; addr_cmd.hci_hdr.opcode = WRITE_BD_ADDR_OPCODE; addr_cmd.hci_hdr.plen = sizeof(bdaddr_t); memcpy(&addr_cmd.addr, bd_addr, sizeof(bdaddr_t)); /* Writing the change BD address command to the UART * This will change the change BD address at the controller * side */ len = write(dev_fd, &addr_cmd, sizeof(addr_cmd)); if (len < 0) { UIM_ERR("Failed to write BD address command"); close(dev_fd); return -1; } /* Read the response for the change BD address command */ if (read_command_complete(dev_fd, WRITE_BD_ADDR_OPCODE) < 0) { close(dev_fd); return -1; } UIM_VER("BD address changed to %s", uim_bd_address); } #ifdef UIM_DEBUG read_firmware_version(dev_fd); #endif } /* After the UART speed has been changed, the IOCTL is * is called to set the line discipline to N_TI_WL */ ldisc = N_TI_WL; if (ioctl(dev_fd, TIOCSETD, &ldisc) < 0) { UIM_ERR(" Can't set line discipline"); close(dev_fd); return -1; } UIM_DBG("Installed N_TI_WL Line displine"); } else { UIM_DBG("Un-Installed N_TI_WL Line displine"); /* UNINSTALL_N_TI_WL - When the Signal is received from KIM */ /* closing UART fd */ close(dev_fd); } return 0; }