root/wiimote/util.c @ 00aa4948876dc0530d8a1e5ab8170a9befa9f14c

Revision 00aa4948876dc0530d8a1e5ab8170a9befa9f14c, 5.3 KB (checked in by dsmith <dsmith@…>, 6 years ago)

wiimote: error checking, comment updates

git-svn-id: http://abstrakraft.org/cwiid/svn/trunk@35 918edb2d-ff29-0410-9de2-eb38e7f22bc7

  • Property mode set to 100644
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 *  03/14/2007: L. Donnie Smith <cwiid@abstrakraft.org>
19 *  * audited error checking (coda and error handler sections)
20 *
21 *  03/05/2007: L. Donnie Smith <cwiid@abstrakraft.org>
22 *  * created wiimote_err_func variable
23 *  * created wiimote_err_default
24 *  * added wiimote parameter to wiimote_err definition and calls
25 *
26 *  03/01/2007: L. Donnie Smith <cwiid@abstrakraft.org>
27 *  * Initial ChangeLog
28 *  * type audit (stdint, const, char booleans)
29 */
30
31#include <stdarg.h>
32#include <stdint.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>
37#include <bluetooth/bluetooth.h>
38#include <bluetooth/hci.h>
39#include <bluetooth/hci_lib.h>
40#include "wiimote_internal.h"
41
42static wiimote_err_t wiimote_err_default;
43
44static wiimote_err_t *wiimote_err_func = &wiimote_err_default;
45
46int wiimote_set_err(wiimote_err_t *err)
47{
48        /* TODO: assuming pointer assignment is atomic operation */
49        /* if it is, and the user doesn't care about race conditions, we don't
50         * either */
51        wiimote_err_func = err;
52        return 0;
53}
54
55static void wiimote_err_default(int id, const char *str, ...)
56{
57        va_list ap;
58
59        va_start(ap, str);
60        vfprintf(stderr, str, ap);
61        fprintf(stderr, "\n");
62        va_end(ap);
63}
64
65void wiimote_err(struct wiimote *wiimote, const char *str, ...)
66{
67        va_list ap;
68
69        if (wiimote_err_func) {
70                va_start(ap, str);
71                if (wiimote) {
72                        (*wiimote_err_func)(wiimote->id, str, ap);
73                }
74                else {
75                        (*wiimote_err_func)(-1, str, ap);
76                }
77                va_end(ap);
78        }
79}
80
81int verify_handshake(struct wiimote *wiimote)
82{
83        unsigned char handshake;
84        if (read(wiimote->ctl_socket, &handshake, 1) != 1) {
85                wiimote_err(wiimote, "Error on read handshake");
86                return -1;
87        }
88        else if ((handshake & BT_TRANS_MASK) != BT_TRANS_HANDSHAKE) {
89                wiimote_err(wiimote, "Handshake expected, non-handshake received");
90                return -1;
91        }
92        else if ((handshake & BT_PARAM_MASK) != BT_PARAM_SUCCESSFUL) {
93                wiimote_err(wiimote, "Non-successful handshake");
94                return -1;
95        }
96
97        return 0;
98}
99
100#define SEND_RPT_BUF_LEN        23
101int send_report(struct wiimote *wiimote, uint8_t flags, uint8_t report,
102                size_t len, const void *data)
103{
104        unsigned char buf[SEND_RPT_BUF_LEN];
105
106        if ((len+2) > SEND_RPT_BUF_LEN) {
107                return -1;
108        }
109
110        buf[0] = BT_TRANS_SET_REPORT | BT_PARAM_OUTPUT;
111        buf[1] = report;
112        memcpy(buf+2, data, len);
113        if (!(flags & SEND_RPT_NO_RUMBLE)) {
114                buf[2] |= wiimote->led_rumble_state & 0x01;
115        }
116
117        if (write(wiimote->ctl_socket, buf, len+2) != (len+2)) {
118                return -1;
119        }
120        else if (verify_handshake(wiimote)) {
121                return -1;
122        }
123
124        return 0;
125}
126
127int exec_write_seq(struct wiimote *wiimote, unsigned int len,
128                   struct write_seq *seq)
129{
130        int i;
131
132        for (i=0; i < len; i++) {
133                switch (seq[i].type) {
134                case WRITE_SEQ_RPT:
135                        if (send_report(wiimote, seq[i].flags, seq[i].report_offset,
136                                        seq[i].len, seq[i].data)) {
137                                return -1;
138                        }
139                        break;
140                case WRITE_SEQ_MEM:
141                        if (wiimote_write(wiimote, seq[i].flags, seq[i].report_offset,
142                                          seq[i].len, seq[i].data)) {
143                                return -1;
144                        }
145                        break;
146                }
147        }
148
149        return 0;
150}
151
152void free_mesg_array(struct mesg_array *array)
153{
154        int i;
155
156        for (i=0; i < array->count; i++) {
157                free(array->mesg[i]);
158        }
159        free(array);
160}
161
162#define MAX_RSP 256
163int wiimote_findfirst(bdaddr_t *bdaddr)
164{
165        /* TODO: I suppose we'll have to sift through BlueZ source to properly
166         * check errors here...
167         */
168        int dev_id;
169        int sock = -1;
170        inquiry_info *dev_list = NULL;
171        int i;
172        int dev_count;
173        int ret = -1;
174        char dev_name[WIIMOTE_CMP_LEN];
175
176        /* Get the first available Bluetooth device */
177        if ((dev_id = hci_get_route(NULL)) == -1) {
178                wiimote_err(NULL, "No Bluetooth device found");
179                ret = -1;
180                goto CODA;
181        }
182        if ((sock = hci_open_dev(dev_id)) == -1) {
183                wiimote_err(NULL, "Error opening Bluetooth device");
184                ret = -1;
185                goto CODA;
186        }
187
188        /* Get Device List */
189        if ((dev_count = hci_inquiry(dev_id, 2, MAX_RSP, NULL, &dev_list,
190                                     IREQ_CACHE_FLUSH)) == -1) {
191                wiimote_err(NULL, "Error on device inquiry");
192                ret = -1;
193                goto CODA;
194        }
195
196        /* Check class and name for Wiimotes */
197        for (i=0; i < dev_count; i++) {
198                if ((dev_list[i].dev_class[0] == WIIMOTE_CLASS_0) &&
199                  (dev_list[i].dev_class[1] == WIIMOTE_CLASS_1) &&
200                  (dev_list[i].dev_class[2] == WIIMOTE_CLASS_2)) {
201                        if (hci_remote_name(sock, &dev_list[i].bdaddr, WIIMOTE_CMP_LEN,
202                                            dev_name, 5000)) {
203                                wiimote_err(NULL, "Error reading device name");
204                        }
205                        else if (strncmp(dev_name, WIIMOTE_NAME, WIIMOTE_CMP_LEN) == 0) {
206                                *bdaddr = dev_list[i].bdaddr;
207                                ret = 0;
208                                break;
209                        }
210                }
211        }
212
213CODA:
214        if (sock != -1) {
215                hci_close_dev(sock);
216        }
217        if (dev_list) {
218                free(dev_list);
219        }
220        return ret;
221}
222
Note: See TracBrowser for help on using the browser.