static int init_uart(char *dev, struct uart_t *u, int send_break, int raw)
{
struct termios ti;
int fd, i;
unsigned long flags = 0;
if (raw)
flags |= 1 << HCI_UART_RAW_DEVICE;
fd = open(dev, O_RDWR | O_NOCTTY); //可进行读写,不将此设备分配作为此进程的控制终端,即Ctrl+C 不能结束此进程
if (fd < 0) {
perror("Can't open serial port");
return -1;
}
tcflush(fd, TCIOFLUSH); //清空数据线
if (tcgetattr(fd, &ti) < 0) { //获得串口设置
perror("Can't get port settings");
return -1;
}
cfmakeraw(&ti); //将终端设置为原始模式控制终端
ti.c_cflag |= CLOCAL;
if (u->flags & FLOW_CTL) //设置流控
ti.c_cflag |= CRTSCTS;
else
ti.c_cflag &= ~CRTSCTS; //本地连接,无调制解调器控制
if (tcsetattr(fd, TCSANOW, &ti) < 0) { //设置串口
perror("Can't set port settings");
return -1;
}
/* Set initial baudrate */
if (set_speed(fd, &ti, u->init_speed) < 0) {
perror("Can't set initial baud rate");
return -1;
}
tcflush(fd, TCIOFLUSH);
if (send_break) {
tcsendbreak(fd, 0); //在串口线上发送0值
usleep(500000); //0.5s发送一个break
}
if (u->init &&
u->init(fd, u, &ti) < 0)
//所有bluez支持的蓝牙串口设备类型构成了一个uart结构数组,通过查找对应的uart类型,并调用这个uart的init成员函数。
return -1;
tcflush(fd, TCIOFLUSH);
/* Set actual baudrate */ //设置实际的波特率
if (set_speed(fd, &ti, u->speed) < 0) {
perror("Can't set baud rate");
return -1;
}
/* Set TTY to N_HCI line discipline */
i = N_HCI;
if (ioctl(fd,
TIOCSETD, &i) < 0) { //
调用内核的tty_ioctl,采用ldisc机制改变hci行规
perror("Can't set line discipline");
return -1;
}
if (flags && ioctl(fd, HCIUARTSETFLAGS, flags) < 0) { //设置串口参数
perror("Can't set UART flags");
return -1;
}
if (ioctl(fd,
HCIUARTSETPROTO, u->proto) < 0) {
//调用内核的tty_ioctl,注册一个hci设备,设置proto为hci设备的proto操作函数集
perror("Can't set device");
return -1;
}
if (u->post &&
u->post(fd, u, &ti) < 0) //调用这个uart的post成员函数
return -1;
return fd;
}