~ubuntu-branches/ubuntu/edgy/hwinfo/edgy

« back to all changes in this revision

Viewing changes to src/hd/braille.c

  • Committer: Bazaar Package Importer
  • Author(s): James Vega
  • Date: 2006-09-28 20:56:06 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060928205606-bgxl69hts04xbx51
Tags: 13.4-1
* New upstream version.
* Switch from dbs to quilt
  - Revamp debian/rules
  - Add quilt and remove dbs from Build-Depends in debian/control
* Remove reference to hwscan(8) from manpage. (closes: #388245)
* Re-wrote manpage from scratch.  Drop docbook-to-man from Build-Depends.
* Remove NEWS.Debian since it is no longer applicable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include <fcntl.h>
 
6
#include <termios.h>
 
7
 
 
8
#include "hd.h"
 
9
#include "hd_int.h"
 
10
#include "braille.h"
 
11
 
 
12
/**
 
13
 * @defgroup BRAILLEint Braille devices
 
14
 * @ingroup  libhdDEVint
 
15
 * @brief Braille displays functions
 
16
 *
 
17
 * @{
 
18
 */
 
19
 
 
20
#if !defined(LIBHD_TINY) && !defined(__sparc__)
 
21
 
 
22
static unsigned do_alva(hd_data_t *hd_data, char *dev_name, int cnt);
 
23
static unsigned do_fhp(hd_data_t *hd_data, char *dev_name, unsigned baud, int cnt);
 
24
static unsigned do_ht(hd_data_t *hd_data, char *dev_name, int cnt);
 
25
static unsigned do_baum(hd_data_t *hd_data, char *dev_name, int cnt);
 
26
 
 
27
void hd_scan_braille(hd_data_t *hd_data)
 
28
{
 
29
  hd_t *hd, *hd_tmp;
 
30
  int cnt = 0;
 
31
  unsigned dev, vend;
 
32
 
 
33
  if(!hd_probe_feature(hd_data, pr_braille)) return;
 
34
 
 
35
  hd_data->module = mod_braille;
 
36
 
 
37
  /* some clean-up */
 
38
  remove_hd_entries(hd_data);
 
39
 
 
40
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
41
    if(
 
42
      hd->base_class.id == bc_comm &&
 
43
      hd->sub_class.id == sc_com_ser &&
 
44
      hd->unix_dev_name &&
 
45
      !hd->tag.ser_skip &&
 
46
      !has_something_attached(hd_data, hd)
 
47
    ) {
 
48
      cnt++;
 
49
      dev = vend = 0;
 
50
 
 
51
      if(hd_probe_feature(hd_data, pr_braille_alva)) {
 
52
        PROGRESS(1, cnt, "alva");
 
53
        vend = MAKE_ID(TAG_SPECIAL, 0x5001);
 
54
        dev = do_alva(hd_data, hd->unix_dev_name, cnt);
 
55
      }
 
56
 
 
57
      if(!dev && hd_probe_feature(hd_data, pr_braille_fhp)) {
 
58
        PROGRESS(1, cnt, "fhp_old");
 
59
        vend = MAKE_ID(TAG_SPECIAL, 0x5002);
 
60
        dev = do_fhp(hd_data, hd->unix_dev_name, B19200, cnt);
 
61
        if(!dev) {
 
62
          PROGRESS(1, cnt, "fhp_el");
 
63
          dev = do_fhp(hd_data, hd->unix_dev_name, B38400, cnt);
 
64
        }
 
65
      }
 
66
 
 
67
      if(!dev && hd_probe_feature(hd_data, pr_braille_ht)) {
 
68
        PROGRESS(1, cnt, "ht");
 
69
        vend = MAKE_ID(TAG_SPECIAL, 0x5003);
 
70
        dev = do_ht(hd_data, hd->unix_dev_name, cnt);
 
71
      }
 
72
 
 
73
      if(!dev && hd_probe_feature(hd_data, pr_braille_baum)) {
 
74
        PROGRESS(1, cnt, "baum");
 
75
        vend = MAKE_ID(TAG_SPECIAL, 0x5004);
 
76
        dev = do_baum(hd_data, hd->unix_dev_name, cnt);
 
77
      }
 
78
 
 
79
      if(dev) {
 
80
        hd_tmp = add_hd_entry(hd_data, __LINE__, 0);
 
81
        hd_tmp->base_class.id = bc_braille;
 
82
        hd_tmp->bus.id = bus_serial;
 
83
        hd_tmp->unix_dev_name = new_str(hd->unix_dev_name);
 
84
        hd_tmp->attached_to = hd->idx;
 
85
        hd_tmp->vendor.id = vend;
 
86
        hd_tmp->device.id = dev;
 
87
      }
 
88
    }
 
89
  }
 
90
}
 
91
 
 
92
 
 
93
/*
 
94
 * autodetect for Alva Braille-displays
 
95
 * Author: marco Skambraks <marco@suse.de>
 
96
 * Suse GmbH Nuernberg
 
97
 *
 
98
 * This is free software, placed under the terms of the
 
99
 * GNU General Public License, as published by the Free Software
 
100
 * Foundation.  Please see the file COPYING for details.
 
101
*/
 
102
 
 
103
/* Communication codes */
 
104
#define BRL_ID  "\033ID="
 
105
 
 
106
 
 
107
#define WAIT_DTR        700000
 
108
#define WAIT_FLUSH      200
 
109
 
 
110
unsigned do_alva(hd_data_t *hd_data, char *dev_name, int cnt)
 
111
{
 
112
  int fd, i, timeout = 100;
 
113
  struct termios oldtio, newtio;                /* old & new terminal settings */
 
114
  int model = -1;
 
115
  unsigned char buffer[sizeof BRL_ID];
 
116
  unsigned dev = 0;
 
117
 
 
118
  PROGRESS(2, cnt, "alva open");
 
119
 
 
120
  /* Open the Braille display device for random access */
 
121
  fd = open(dev_name, O_RDWR | O_NOCTTY);
 
122
  if(fd < 0) return 0;
 
123
 
 
124
  tcgetattr(fd, &oldtio);       /* save current settings */
 
125
 
 
126
  /* Set flow control and 8n1, enable reading */
 
127
  memset(&newtio, 0, sizeof newtio);
 
128
  newtio.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD;
 
129
  /* Ignore bytes with parity errors and make terminal raw and dumb */
 
130
  newtio.c_iflag = IGNPAR;
 
131
  newtio.c_oflag = 0;           /* raw output */
 
132
  newtio.c_lflag = 0;           /* don't echo or generate signals */
 
133
  newtio.c_cc[VMIN] = 0;        /* set nonblocking read */
 
134
  newtio.c_cc[VTIME] = 0;
 
135
 
 
136
  PROGRESS(3, cnt, "alva init ok");
 
137
 
 
138
  PROGRESS(4, cnt, "alva read data");
 
139
 
 
140
  /* autodetecting ABT model */
 
141
  /* to force DTR off */
 
142
  cfsetispeed(&newtio, B0);
 
143
  cfsetospeed(&newtio, B0);
 
144
  tcsetattr(fd, TCSANOW, &newtio);      /* activate new settings */
 
145
  usleep(WAIT_DTR);
 
146
 
 
147
  tcflush(fd, TCIOFLUSH);               /* clean line */
 
148
  usleep(WAIT_FLUSH);
 
149
 
 
150
  /* DTR back on */
 
151
  cfsetispeed(&newtio, B9600);
 
152
  cfsetospeed(&newtio, B9600);
 
153
  tcsetattr(fd, TCSANOW, &newtio);      /* activate new settings */
 
154
  usleep(WAIT_DTR);                     /* give time to send ID string */
 
155
 
 
156
  if((i = read(fd, buffer, sizeof buffer)) == sizeof buffer) {
 
157
    if(!strncmp(buffer, BRL_ID, sizeof BRL_ID - 1)) {
 
158
      /* Find out which model we are connected to... */
 
159
      switch(model = buffer[sizeof buffer - 1])
 
160
      {
 
161
        case    1:
 
162
        case    2:
 
163
        case    3:
 
164
        case    4:
 
165
        case 0x0b:
 
166
        case 0x0d:
 
167
        case 0x0e:
 
168
         dev = MAKE_ID(TAG_SPECIAL, model);
 
169
         break;
 
170
      }
 
171
    }
 
172
  }
 
173
  ADD2LOG("alva.%d@%s[%d]: ", timeout, dev_name, i);
 
174
  if(i > 0) hexdump(&hd_data->log, 1, i, buffer);
 
175
  ADD2LOG("\n");
 
176
 
 
177
  PROGRESS(5, cnt, "alva read done");
 
178
 
 
179
  /* reset serial lines */
 
180
  tcflush(fd, TCIOFLUSH);
 
181
  tcsetattr(fd, TCSAFLUSH, &oldtio);
 
182
  close(fd);
 
183
 
 
184
  return dev;
 
185
}
 
186
 
 
187
 
 
188
/*
 
189
 * autodetect for Papenmeier Braille-displays
 
190
 * Author: marco Skambraks <marco@suse.de>
 
191
 * Suse GmbH Nuernberg
 
192
 *
 
193
 * This is free software, placed under the terms of the
 
194
 * GNU General Public License, as published by the Free Software
 
195
 * Foundation.  Please see the file COPYING for details.
 
196
 */
 
197
 
 
198
unsigned do_fhp(hd_data_t *hd_data, char *dev_name, unsigned baud, int cnt)
 
199
{
 
200
  int fd, i;
 
201
  char crash[] = { 2, 'S', 0, 0, 0, 0 };
 
202
  unsigned char buf[10];
 
203
  struct termios oldtio, newtio;        /* old & new terminal settings */
 
204
  unsigned dev;
 
205
 
 
206
  PROGRESS(2, cnt, "fhp open");
 
207
 
 
208
  /* Now open the Braille display device for random access */
 
209
  fd = open(dev_name, O_RDWR | O_NOCTTY);
 
210
  if(fd < 0) return 0;
 
211
 
 
212
  tcgetattr(fd, &oldtio);       /* save current settings */
 
213
 
 
214
  /* Set bps, flow control and 8n1, enable reading */
 
215
  memset(&newtio, 0, sizeof newtio);
 
216
  newtio.c_cflag = baud | CS8 | CLOCAL | CREAD;
 
217
 
 
218
  /* Ignore bytes with parity errors and make terminal raw and dumb */
 
219
  newtio.c_iflag = IGNPAR;
 
220
  newtio.c_oflag = 0;                           /* raw output */
 
221
  newtio.c_lflag = 0;                           /* don't echo or generate signals */
 
222
  newtio.c_cc[VMIN] = 0;                        /* set nonblocking read */
 
223
  newtio.c_cc[VTIME] = 0;
 
224
  tcflush(fd, TCIFLUSH);                        /* clean line */
 
225
  tcsetattr(fd, TCSANOW, &newtio);              /* activate new settings */
 
226
 
 
227
  PROGRESS(3, cnt, "fhp init ok");
 
228
 
 
229
  crash[2] = 0x200 >> 8;
 
230
  crash[3] = 0x200 & 0xff;
 
231
  crash[5] = (7+10) & 0xff;
 
232
 
 
233
  write(fd, crash, sizeof crash);
 
234
  write(fd, "1111111111",10);
 
235
  write(fd, "\03", 1);
 
236
 
 
237
  crash[2] = 0x0 >> 8;
 
238
  crash[3] = 0x0 & 0xff;
 
239
  crash[5] = 5 & 0xff;
 
240
 
 
241
  write(fd, crash, sizeof crash);
 
242
  write(fd, "1111111111", 10);
 
243
  write(fd, "\03", 1);
 
244
 
 
245
  usleep(500000);               /* 100000 should be enough */
 
246
 
 
247
  PROGRESS(4, cnt, "fhp write ok");
 
248
 
 
249
  i = read(fd, &buf, 10);
 
250
 
 
251
  PROGRESS(5, cnt, "fhp read done");
 
252
 
 
253
  ADD2LOG("fhp@%s[%d]: ", dev_name, i);
 
254
  if(i > 0) hexdump(&hd_data->log, 1, i, buf);
 
255
  ADD2LOG("\n");
 
256
 
 
257
  dev = 0;
 
258
  if(i == 10 && buf[0] == 0x02 && buf[1] == 0x49) {
 
259
    switch(buf[2]) {
 
260
      case  1:
 
261
      case  2:
 
262
      case  3:
 
263
      case 64:
 
264
      case 65:
 
265
      case 66:
 
266
      case 67:
 
267
      case 68:
 
268
        dev = buf[2];
 
269
        dev = MAKE_ID(TAG_SPECIAL, dev);
 
270
        break;
 
271
    }
 
272
  }
 
273
  if(!dev) ADD2LOG("no fhp display: 0x%02x\n", i >= 2 ? buf[2] : 0);
 
274
 
 
275
  /* reset serial lines */
 
276
  tcflush(fd, TCIOFLUSH);
 
277
  tcsetattr(fd, TCSAFLUSH, &oldtio);
 
278
  close(fd);
 
279
 
 
280
  return dev;
 
281
}
 
282
 
 
283
 
 
284
/*
 
285
 * autodetect for Handy Tech  Braille-displays
 
286
 * Author: marco Skambraks <marco@suse.de>
 
287
 * Suse GmbH Nuernberg
 
288
 *
 
289
 * This is free software, placed under the terms of the
 
290
 * GNU General Public License, as published by the Free Software
 
291
 * Foundation.  Please see the file COPYING for details.
 
292
*/
 
293
 
 
294
unsigned do_ht(hd_data_t *hd_data, char *dev_name, int cnt)
 
295
{
 
296
  int fd, i;
 
297
  unsigned char code = 0xff, buf[2] = { 0, 0 };
 
298
  struct termios oldtio, newtio;
 
299
  unsigned dev = 0;
 
300
 
 
301
  PROGRESS(2, cnt, "ht open");
 
302
 
 
303
  fd = open(dev_name, O_RDWR | O_NOCTTY);
 
304
  if(fd < 0) return 0;
 
305
 
 
306
  tcgetattr(fd, &oldtio);
 
307
 
 
308
  newtio = oldtio;
 
309
  newtio.c_cflag = CLOCAL | PARODD | PARENB | CREAD | CS8;
 
310
  newtio.c_iflag = IGNPAR;
 
311
  newtio.c_oflag = 0;
 
312
  newtio.c_lflag = 0;
 
313
  newtio.c_cc[VMIN] = 0;
 
314
  newtio.c_cc[VTIME] = 0;
 
315
 
 
316
  i = 0;
 
317
  /*
 
318
   * Force down DTR, flush any pending data and then the port to what we
 
319
   * want it to be
 
320
   */
 
321
  if(
 
322
    !(
 
323
      cfsetispeed(&newtio, B0) ||
 
324
      cfsetospeed(&newtio, B0) ||
 
325
      tcsetattr(fd, TCSANOW, &newtio) ||
 
326
      tcflush(fd, TCIOFLUSH) ||
 
327
      cfsetispeed(&newtio, B19200) ||
 
328
      cfsetospeed(&newtio, B19200) ||
 
329
      tcsetattr(fd, TCSANOW, &newtio)
 
330
    )
 
331
  ) {
 
332
    /* Pause to let them take effect */
 
333
    usleep(500);
 
334
 
 
335
    PROGRESS(3, cnt, "ht init ok");
 
336
 
 
337
    write(fd, &code, 1);        /* reset brl */
 
338
    usleep(5000);               /* wait for reset */
 
339
 
 
340
    PROGRESS(4, cnt, "ht write ok");
 
341
 
 
342
    read(fd, buf, 1);
 
343
    i = 1;
 
344
 
 
345
    PROGRESS(5, cnt, "ht read done");
 
346
 
 
347
    if(buf[0] == 0xfe) {        /* resetok now read id */
 
348
      usleep(5000);
 
349
      read(fd, buf + 1, 1);
 
350
      i = 2;
 
351
 
 
352
      PROGRESS(6, cnt, "ht read done");
 
353
 
 
354
      switch(buf[1]) {
 
355
        case 0x05:
 
356
        case 0x09:
 
357
        case 0x44:
 
358
        case 0x74:
 
359
        case 0x80:
 
360
        case 0x84:
 
361
        case 0x88:
 
362
        case 0x89:
 
363
          dev = buf[1];
 
364
          dev = MAKE_ID(TAG_SPECIAL, dev);
 
365
          break;
 
366
      }
 
367
    }
 
368
  }
 
369
 
 
370
  ADD2LOG("ht@%s[%d]: ", dev_name, i);
 
371
  if(i > 0) hexdump(&hd_data->log, 1, i, buf);
 
372
  ADD2LOG("\n");
 
373
 
 
374
  if(!dev) ADD2LOG("no ht display: 0x%02x\n", buf[1]);
 
375
 
 
376
  /* reset serial lines */
 
377
  tcflush(fd, TCIOFLUSH);
 
378
  tcsetattr(fd, TCSAFLUSH, &oldtio);
 
379
  close(fd);
 
380
 
 
381
  return dev;
 
382
}
 
383
 
 
384
 
 
385
/*
 
386
 * autodetect for Baum Braille-displays
 
387
 * Author: marco Skambraks <marco@suse.de>
 
388
 * Suse GmbH Nuernberg
 
389
 *
 
390
 * This is free software, placed under the terms of the
 
391
 * GNU General Public License, as published by the Free Software
 
392
 * Foundation.  Please see the file COPYING for details.
 
393
*/
 
394
 
 
395
#define BAUDRATE        B19200          /* But both run at 19k2 */
 
396
#define MAXREAD         18
 
397
 
 
398
unsigned do_baum(hd_data_t *hd_data, char *dev_name, int cnt)
 
399
{
 
400
  static char device_id[] = { 0x1b, 0x84 };
 
401
  int fd;
 
402
  struct termios oldtio, curtio;
 
403
  unsigned char buf[MAXREAD + 1];
 
404
  int i;
 
405
 
 
406
  PROGRESS(2, cnt, "baum open");
 
407
 
 
408
  fd = open(dev_name, O_RDWR | O_NOCTTY);
 
409
  if(fd < 0) return 0;
 
410
 
 
411
  tcgetattr(fd, &curtio);
 
412
 
 
413
  oldtio = curtio;
 
414
  cfmakeraw(&curtio);
 
415
 
 
416
  /* no SIGTTOU to backgrounded processes */
 
417
  curtio.c_lflag &= ~TOSTOP;
 
418
  curtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
 
419
  /* no input parity check, no XON/XOFF */
 
420
  curtio.c_iflag &= ~(INPCK | ~IXOFF);
 
421
 
 
422
  curtio.c_cc[VTIME] = 1;       /* 0.1s timeout between chars on input */
 
423
  curtio.c_cc[VMIN] = 0;        /* no minimum input */
 
424
 
 
425
  tcsetattr(fd, TCSAFLUSH, &curtio);
 
426
 
 
427
  /* write ID-request */
 
428
  write(fd, device_id, sizeof device_id);
 
429
 
 
430
  /* wait for response */
 
431
  usleep(100000);
 
432
 
 
433
  PROGRESS(3, cnt, "baum write ok");
 
434
 
 
435
  i = read(fd, buf, sizeof buf - 1);
 
436
  buf[sizeof buf - 1] = 0;
 
437
 
 
438
  PROGRESS(4, cnt, "baum read done");
 
439
 
 
440
  ADD2LOG("baum@%s[%d]: ", dev_name, i);
 
441
  if(i > 0) hexdump(&hd_data->log, 1, i, buf);
 
442
  ADD2LOG("\n");
 
443
 
 
444
  /* reset serial lines */
 
445
  tcflush(fd, TCIOFLUSH);
 
446
  tcsetattr(fd, TCSAFLUSH, &oldtio);
 
447
  close(fd);
 
448
 
 
449
  if(!strcmp(buf + 2, "Baum Vario40")) return 1;
 
450
  if(!strcmp(buf + 2, "Baum Vario80")) return 2;
 
451
 
 
452
  return 0;
 
453
}
 
454
 
 
455
 
 
456
#endif  /* !defined(LIBHD_TINY) && !defined(__sparc__) */
 
457
 
 
458
/** @} */
 
459