sir.c revision 1.1 1 1.1 augustss /* $NetBSD: sir.c,v 1.1 2001/12/05 14:50:14 augustss Exp $ */
2 1.1 augustss
3 1.1 augustss /*
4 1.1 augustss * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 1.1 augustss * All rights reserved.
6 1.1 augustss *
7 1.1 augustss * This code is derived from software contributed to The NetBSD Foundation
8 1.1 augustss * by Lennart Augustsson (lennart (at) augustsson.net) and Tommy Bohlin
9 1.1 augustss * (tommy (at) gatespace.com).
10 1.1 augustss *
11 1.1 augustss * Redistribution and use in source and binary forms, with or without
12 1.1 augustss * modification, are permitted provided that the following conditions
13 1.1 augustss * are met:
14 1.1 augustss * 1. Redistributions of source code must retain the above copyright
15 1.1 augustss * notice, this list of conditions and the following disclaimer.
16 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 augustss * notice, this list of conditions and the following disclaimer in the
18 1.1 augustss * documentation and/or other materials provided with the distribution.
19 1.1 augustss * 3. All advertising materials mentioning features or use of this software
20 1.1 augustss * must display the following acknowledgement:
21 1.1 augustss * This product includes software developed by the NetBSD
22 1.1 augustss * Foundation, Inc. and its contributors.
23 1.1 augustss * 4. Neither the name of The NetBSD Foundation nor the names of its
24 1.1 augustss * contributors may be used to endorse or promote products derived
25 1.1 augustss * from this software without specific prior written permission.
26 1.1 augustss *
27 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 1.1 augustss * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 1.1 augustss * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 1.1 augustss * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 1.1 augustss * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 1.1 augustss * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 1.1 augustss * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 1.1 augustss * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 1.1 augustss * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 1.1 augustss * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 1.1 augustss * POSSIBILITY OF SUCH DAMAGE.
38 1.1 augustss */
39 1.1 augustss
40 1.1 augustss /*
41 1.1 augustss * Framing originally written by Tommy Bohlin.
42 1.1 augustss */
43 1.1 augustss
44 1.1 augustss #include <sys/param.h>
45 1.1 augustss #include <sys/conf.h>
46 1.1 augustss #include <sys/systm.h>
47 1.1 augustss
48 1.1 augustss #include <dev/ir/sir.h>
49 1.1 augustss
50 1.1 augustss /*
51 1.1 augustss * CRC computation table
52 1.1 augustss */
53 1.1 augustss const u_int16_t irda_fcstab[] = {
54 1.1 augustss 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
55 1.1 augustss 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
56 1.1 augustss 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
57 1.1 augustss 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
58 1.1 augustss 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
59 1.1 augustss 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
60 1.1 augustss 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
61 1.1 augustss 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
62 1.1 augustss 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
63 1.1 augustss 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
64 1.1 augustss 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
65 1.1 augustss 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
66 1.1 augustss 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
67 1.1 augustss 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
68 1.1 augustss 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
69 1.1 augustss 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
70 1.1 augustss 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
71 1.1 augustss 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
72 1.1 augustss 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
73 1.1 augustss 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
74 1.1 augustss 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
75 1.1 augustss 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
76 1.1 augustss 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
77 1.1 augustss 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
78 1.1 augustss 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
79 1.1 augustss 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
80 1.1 augustss 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
81 1.1 augustss 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
82 1.1 augustss 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
83 1.1 augustss 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
84 1.1 augustss 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
85 1.1 augustss 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
86 1.1 augustss };
87 1.1 augustss
88 1.1 augustss
89 1.1 augustss #define MAX_IRDA_FRAME 5000 /* XXX what is it? */
90 1.1 augustss
91 1.1 augustss #define PUTC(c) if (p < end) *p++ = (c)
92 1.1 augustss #define PUTESC(c) \
93 1.1 augustss if (c == SIR_BOF || c == SIR_EOF || c == SIR_CE) { \
94 1.1 augustss PUTC(SIR_CE); \
95 1.1 augustss PUTC(SIR_ESC_BIT^c); \
96 1.1 augustss } else { \
97 1.1 augustss PUTC(c); \
98 1.1 augustss }
99 1.1 augustss
100 1.1 augustss int
101 1.1 augustss irda_sir_frame(u_int8_t *obuf, u_int maxlen, struct uio *uio, u_int ebofs)
102 1.1 augustss {
103 1.1 augustss u_int8_t ibuf[MAX_IRDA_FRAME];
104 1.1 augustss u_int8_t *p, *end, *cp;
105 1.1 augustss size_t n;
106 1.1 augustss int error;
107 1.1 augustss int i;
108 1.1 augustss int c;
109 1.1 augustss u_int16_t ofcs;
110 1.1 augustss
111 1.1 augustss n = uio->uio_resid;
112 1.1 augustss if (n > MAX_IRDA_FRAME)
113 1.1 augustss return (EINVAL);
114 1.1 augustss error = uiomove(ibuf, n, uio);
115 1.1 augustss if (error)
116 1.1 augustss return (-error);
117 1.1 augustss
118 1.1 augustss end = obuf + maxlen;
119 1.1 augustss
120 1.1 augustss for (i = 0; i < ebofs; i++)
121 1.1 augustss PUTC(SIR_EXTRA_BOF);
122 1.1 augustss PUTC(SIR_BOF);
123 1.1 augustss
124 1.1 augustss ofcs = INITFCS;
125 1.1 augustss cp = ibuf;
126 1.1 augustss while (n-- > 0) {
127 1.1 augustss c = *cp++;
128 1.1 augustss ofcs = updateFCS(ofcs, c);
129 1.1 augustss PUTESC(c);
130 1.1 augustss }
131 1.1 augustss
132 1.1 augustss ofcs = ~ofcs;
133 1.1 augustss c = ofcs & 0xff;
134 1.1 augustss PUTESC(c);
135 1.1 augustss c = (ofcs >> 8) & 0xff;
136 1.1 augustss PUTESC(c);
137 1.1 augustss PUTC(SIR_EOF);
138 1.1 augustss
139 1.1 augustss if (p < end)
140 1.1 augustss return (p - obuf);
141 1.1 augustss else
142 1.1 augustss return (-EINVAL);
143 1.1 augustss }
144