root/branches/dev/libcwiid/process.c

Revision 115, 7.5 kB (checked in by dsmith, 2 years ago)

fixed error message reporting

Line 
1 /* Copyright (C) 2007 L. Donnie Smith <cwiid@abstrakraft.org>
2  *
3  *  This program is free software; you can redistribute it and/or modify
4  *  it under the terms of the GNU General Public License as published by
5  *  the Free Software Foundation; either version 2 of the License, or
6  *  (at your option) any later version.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16  *
17  *  ChangeLog:
18  *  2007-05-16 L. Donnie Smith <cwiid@abstrakraft.org>
19  *  * process_err adds error_mesg to mesg_array
20  *
21  *  2007-04-24 L. Donnie Smith <cwiid@abstrakraft.org>
22  *  * created for API overhaul (moved from old event.c)
23  */
24
25 #include <unistd.h>
26 #include "cwiid_internal.h"
27
28 int process_error(struct wiimote *wiimote, ssize_t len, struct mesg_array *ma)
29 {
30         struct cwiid_error_mesg *error_mesg;
31
32         error_mesg = &ma->array[ma->count++].error_mesg;
33         error_mesg->type = CWIID_MESG_ERROR;
34         if (len == 0) {
35                 error_mesg->error = CWIID_ERROR_DISCONNECT;
36         }
37         else {
38                 error_mesg->error = CWIID_ERROR_COMM;
39         }
40
41         if (cancel_rw(wiimote)) {
42                 cwiid_err(wiimote, "RW cancel error");
43         }
44
45         return 0;
46 }
47
48 int process_status(struct wiimote *wiimote, const unsigned char *data,
49                    struct mesg_array *ma)
50 {
51         struct cwiid_status_mesg status_mesg;
52
53         status_mesg.type = CWIID_MESG_STATUS;
54         status_mesg.battery = data[5];
55         if (data[2] & 0x02) {
56                 /* status_thread will figure out what it is */
57                 status_mesg.ext_type = CWIID_EXT_UNKNOWN;
58         }
59         else {
60                 status_mesg.ext_type = CWIID_EXT_NONE;
61         }
62
63         if (write(wiimote->status_pipe[1], &status_mesg, sizeof status_mesg)
64           != sizeof status_mesg) {
65                 cwiid_err(wiimote, "Status pipe write error");
66                 return -1;
67         }
68
69         return 0;
70 }
71
72 int process_btn(struct wiimote *wiimote, const unsigned char *data,
73                 struct mesg_array *ma)
74 {
75         struct cwiid_btn_mesg *btn_mesg;
76         uint16_t buttons;
77
78         buttons = (data[0] & BTN_MASK_0)<<8 |
79                   (data[1] & BTN_MASK_1);
80         if (wiimote->state.rpt_mode & CWIID_RPT_BTN) {
81                 if ((wiimote->state.buttons != buttons) ||
82                   (wiimote->flags & CWIID_FLAG_REPEAT_BTN)) {
83                         btn_mesg = &ma->array[ma->count++].btn_mesg;
84                         btn_mesg->type = CWIID_MESG_BTN;
85                         btn_mesg->buttons = buttons;
86                 }
87         }
88
89         return 0;
90 }
91
92 int process_acc(struct wiimote *wiimote, const unsigned char *data,
93                 struct mesg_array *ma)
94 {
95         struct cwiid_acc_mesg *acc_mesg;
96
97         if (wiimote->state.rpt_mode & CWIID_RPT_ACC) {
98                 acc_mesg = &ma->array[ma->count++].acc_mesg;
99                 acc_mesg->type = CWIID_MESG_ACC;
100                 acc_mesg->acc[CWIID_X] = data[0];
101                 acc_mesg->acc[CWIID_Y] = data[1];
102                 acc_mesg->acc[CWIID_Z] = data[2];
103         }
104
105         return 0;
106 }
107
108 int process_ir10(struct wiimote *wiimote, const unsigned char *data,
109                  struct mesg_array *ma)
110 {
111         struct cwiid_ir_mesg *ir_mesg;
112         int i;
113         const unsigned char *block;
114
115         if (wiimote->state.rpt_mode & CWIID_RPT_IR) {
116                 ir_mesg = &ma->array[ma->count++].ir_mesg;
117                 ir_mesg->type = CWIID_MESG_IR;
118
119                 for (i=0, block=data; i < CWIID_IR_SRC_COUNT; i+=2, block+=5) {
120                         if (block[0] == 0xFF) {
121                                 ir_mesg->src[i].valid = 0;
122                         }
123                         else {
124                                 ir_mesg->src[i].valid = 1;
125                                 ir_mesg->src[i].pos[CWIID_X] = ((uint16_t)block[2] & 0x30)<<4 |
126                                                                 (uint16_t)block[0];
127                                 ir_mesg->src[i].pos[CWIID_Y] = ((uint16_t)block[2] & 0xC0)<<2 |
128                                                                 (uint16_t)block[1];
129                                 ir_mesg->src[i].size = -1;
130                         }
131
132                         if (block[3] == 0xFF) {
133                                 ir_mesg->src[i+1].valid = 0;
134                         }
135                         else {
136                                 ir_mesg->src[i+1].valid = 1;
137                                 ir_mesg->src[i+1].pos[CWIID_X] =
138                                                                ((uint16_t)block[2] & 0x03)<<8 |
139                                                                 (uint16_t)block[3];
140                                 ir_mesg->src[i+1].pos[CWIID_Y] =
141                                                                ((uint16_t)block[2] & 0x0C)<<6 |
142                                                                 (uint16_t)block[4];
143                                 ir_mesg->src[i+1].size = -1;
144                         }
145                 }
146         }
147
148         return 0;
149 }
150
151 int process_ir12(struct wiimote *wiimote, const unsigned char *data,
152                  struct mesg_array *ma)
153 {
154         struct cwiid_ir_mesg *ir_mesg;
155         int i;
156         const unsigned char *block;
157
158         if (wiimote->state.rpt_mode & CWIID_RPT_IR) {
159                 ir_mesg = &ma->array[ma->count++].ir_mesg;
160                 ir_mesg->type = CWIID_MESG_IR;
161
162                 for (i=0, block=data; i < CWIID_IR_SRC_COUNT; i++, block+=3) {
163                         if (block[0] == 0xFF) {
164                                 ir_mesg->src[i].valid = 0;
165                         }
166                         else {
167                                 ir_mesg->src[i].valid = 1;
168                                 ir_mesg->src[i].pos[CWIID_X] = ((uint16_t)block[2] & 0x30)<<4 |
169                                                                 (uint16_t)block[0];
170                                 ir_mesg->src[i].pos[CWIID_Y] = ((uint16_t)block[2] & 0xC0)<<2 |
171                                                                 (uint16_t)block[1];
172                                 ir_mesg->src[i].size = block[2] & 0x0F;
173                         }
174                 }
175         }
176
177         return 0;
178 }
179
180 int process_ext(struct wiimote *wiimote, unsigned char *data,
181                 unsigned char len, struct mesg_array *ma)
182 {
183         struct cwiid_nunchuk_mesg *nunchuk_mesg;
184         struct cwiid_classic_mesg *classic_mesg;
185         int i;
186
187         switch (wiimote->state.ext_type) {
188         case CWIID_EXT_NONE:
189                 cwiid_err(wiimote, "Received unexpected extension report");
190                 break;
191         case CWIID_EXT_UNKNOWN:
192                 break;
193         case CWIID_EXT_NUNCHUK:
194                 if (wiimote->state.rpt_mode & CWIID_RPT_NUNCHUK) {
195                         nunchuk_mesg = &ma->array[ma->count++].nunchuk_mesg;
196                         nunchuk_mesg->type = CWIID_MESG_NUNCHUK;
197                         nunchuk_mesg->stick[CWIID_X] = DECODE(data[0]);
198                         nunchuk_mesg->stick[CWIID_Y] = DECODE(data[1]);
199                         nunchuk_mesg->acc[CWIID_X] = DECODE(data[2]);
200                         nunchuk_mesg->acc[CWIID_Y] = DECODE(data[3]);
201                         nunchuk_mesg->acc[CWIID_Z] = DECODE(data[4]);
202                         nunchuk_mesg->buttons = ~DECODE(data[5]) & NUNCHUK_BTN_MASK;
203                 }
204                 break;
205         case CWIID_EXT_CLASSIC:
206                 if (wiimote->state.rpt_mode & CWIID_RPT_CLASSIC) {
207                         classic_mesg = &ma->array[ma->count++].classic_mesg;
208                         classic_mesg->type = CWIID_MESG_CLASSIC;
209
210                         for (i=0; i < 6; i++) {
211                                 data[i] = DECODE(data[i]);
212                         }
213
214                         classic_mesg->l_stick[CWIID_X] = data[0] & 0x3F;
215                         classic_mesg->l_stick[CWIID_Y] = data[1] & 0x3F;
216                         classic_mesg->r_stick[CWIID_X] = (data[0] & 0xC0)>>3 |
217                                                          (data[1] & 0xC0)>>5 |
218                                                          (data[2] & 0x80)>>7;
219                         classic_mesg->r_stick[CWIID_Y] = data[2] & 0x1F;
220                         classic_mesg->l = (data[2] & 0x60)>>2 |
221                                           (data[3] & 0xE0)>>5;
222                         classic_mesg->r = data[3] & 0x1F;
223                         classic_mesg->buttons = ~((uint16_t)data[4]<<8 |
224                                                   (uint16_t)data[5]);
225                 }
226                 break;
227         }
228
229         return 0;
230 }
231
232 int process_read(struct wiimote *wiimote, unsigned char *data)
233 {
234         struct rw_mesg rw_mesg;
235
236         if (wiimote->rw_status != RW_READ) {
237                 cwiid_err(wiimote, "Received unexpected read report");
238                 return -1;
239         }
240
241         rw_mesg.type = RW_READ;
242         rw_mesg.len = (data[0]>>4)+1;
243         rw_mesg.error = data[0] & 0x0F;
244         memcpy(&rw_mesg.data, data+3, rw_mesg.len);
245
246         if (write(wiimote->rw_pipe[1], &rw_mesg, sizeof rw_mesg) !=
247           sizeof rw_mesg) {
248                 cwiid_err(wiimote, "RW pipe write error");
249                 return -1;
250         }
251
252         return 0;
253 }
254
255 int process_write(struct wiimote *wiimote, unsigned char *data)
256 {
257         struct rw_mesg rw_mesg;
258
259         if (wiimote->rw_status != RW_WRITE) {
260                 cwiid_err(wiimote, "Received unexpected write report");
261                 return -1;
262         }
263
264         rw_mesg.type = RW_WRITE;
265         rw_mesg.error = data[0];
266
267         if (write(wiimote->rw_pipe[1], &rw_mesg, sizeof rw_mesg) !=
268           sizeof rw_mesg) {
269                 cwiid_err(wiimote, "RW pipe write error");
270                 return -1;
271         }
272
273         return 0;
274 }
Note: See TracBrowser for help on using the browser.