Project

General

Profile

« Previous | Next » 

Revision c71ca2b5

Allow opening a tty by giving its (usb) serial number

Before opening the given path, try to match a usb serial number. If there
is a match, the corresponding device node is openened.

This uses libudev, so it's for linux only.

Added by Anthony Mallet over 3 years ago

View differences:

codels/tty.c
32 32
# include <linux/serial.h> /* for TIOCGSERIAL and ASYNC_LOW_LATENCY */
33 33
#endif
34 34

  
35
#ifdef __linux__
36
# include <libudev.h>
37
#endif
38

  
35 39
#include "codels.h"
36 40

  
37 41

  
38 42
/* --- mk_open_tty --------------------------------------------------------- */
39 43

  
44
static const char *	usb_serial_to_tty(const char *serial);
45

  
40 46
/* Open a serial port, configure to the given baud rate */
41 47
int
42 48
mk_open_tty(const char *device, uint32_t speed)
43 49
{
50
  const char *path;
44 51
  struct termios t;
45 52
  speed_t baud;
46 53
  int fd;
......
54 61
#endif
55 62
#ifndef B500000
56 63
# define B500000 500000U
64
#endif
65
#ifndef B2000000
66
# define B2000000 2000000U
57 67
#endif
58 68
  switch(speed) {
59 69
    case 57600:		baud = B57600; break;
......
64 74
    default: errno = EINVAL; return -1;
65 75
  }
66 76

  
77
  /* try to match a serial id first */
78
  path = usb_serial_to_tty(device);
79
  if (path) device = path;
80

  
67 81
  /* open non-blocking */
68 82
  fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
69 83
  if (fd < 0) return fd;
......
119 133
}
120 134

  
121 135

  
136
/* --- usb_serial_to_tty --------------------------------------------------- */
137

  
138
/* Return a tty device matching the "serial" string */
139

  
140
static const char *
141
usb_serial_to_tty(const char *serial)
142
{
143
#ifdef __linux__
144
  struct udev *udev;
145
  struct udev_enumerate *scan = NULL;
146
  struct udev_list_entry *ttys, *tty;
147
  struct udev_device *dev = NULL, *usb;
148
  const char *path = NULL;
149

  
150
  udev = udev_new();
151
  if (!udev) return NULL;
152

  
153
  /* iterate over tty devices */
154
  scan = udev_enumerate_new(udev);
155
  if (udev_enumerate_add_match_subsystem(scan, "tty")) goto done;
156
  if (udev_enumerate_scan_devices(scan)) goto done;
157

  
158
  ttys = udev_enumerate_get_list_entry(scan);
159
  udev_list_entry_foreach(tty, ttys) {
160
    const char *sysfs, *userial;
161

  
162
    /* get sysfs entry for the device and create a corresponding udev_device */
163
    if (dev) udev_device_unref(dev);
164
    sysfs = udev_list_entry_get_name(tty);
165
    dev = udev_device_new_from_syspath(udev, sysfs);
166

  
167
    /* get the USB device, it any */
168
    usb = udev_device_get_parent_with_subsystem_devtype(
169
      dev, "usb", "usb_device");
170
    if (!usb) continue;
171

  
172
    userial = udev_device_get_sysattr_value(usb, "serial");
173
    if (!userial || strcmp(userial, serial)) continue;
174

  
175
    /* got a match, return the tty path */
176
    path = strdup(udev_device_get_devnode(dev)); /* this will leak ... */
177
    break;
178
  }
179
  if (dev) udev_device_unref(dev);
180

  
181
done:
182
  if (scan) udev_enumerate_unref(scan);
183
  if (udev) udev_unref(udev);
184
  return path;
185

  
186
#else
187
  return NULL; /* if needed, implement this for other OSes */
188
#endif
189
}
190

  
191

  
122 192
/* --- mk_wait_msg --------------------------------------------------------- */
123 193

  
124 194
int

Also available in: Unified diff