root/wiimote/util.c @ a339960844acef82f06e6c4ba82575fafc4e50ac

Revision a339960844acef82f06e6c4ba82575fafc4e50ac, 5.2 KB (checked in by dsmith <dsmith@…>, 6 years ago)

added wiimote_set_err

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