root/trunk/libcwiid/bluetooth.c

Revision 183, 5.3 kB (checked in by dsmith, 1 month ago)

Update for BlueZ changes.

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-04-24 L. Donnie Smith (cwiid@abstrakraft.org>
19  *  * revised error messages
20  *
21  *  2007-04-12 L. Donnie Smith <cwiid@abstrakraft.org>
22  *  * streamlined wiimote filter
23  *
24  *  2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org>
25  *  * renamed wiimote to libcwiid, renamed structures accordingly
26  *
27  *  2007-04-07 L. Donnie Smith <cwiid@abstrakraft.org>
28  *  * changed cwiid_info.class to btclass
29  *
30  *  2007-04-03 L. Donnie Smith <cwiid@abstrakraft.org>
31  *  * fixed cwiid_find_wiimote seg fault
32  *
33  *  2007-04-02 L. Donnie Smith <cwiid@abstrakraft.org>
34  *  * exception handling bugs
35  *
36  *  2007-04-01 L. Donnie Smith <cwiid@abstrakraft.org>
37  *  * created file
38  */
39
40 #include <stdlib.h>
41 #include <string.h>
42 #include <bluetooth/bluetooth.h>
43 #include <bluetooth/hci.h>
44 #include <bluetooth/hci_lib.h>
45 #include "cwiid_internal.h"
46
47 /* When filtering wiimotes, in order to avoid having to store the
48  * remote names before the blue_dev array is malloced (because we don't
49  * yet know how many wiimotes there are, we'll assume there are no more
50  * than dev_count, and realloc to the actual number afterwards, since
51  * reallocing to a smaller chunk should be fast. */
52 #define BT_MAX_INQUIRY 256
53 /* timeout in 2 second units */
54 int cwiid_get_bdinfo_array(int dev_id, unsigned int timeout, int max_bdinfo,
55                            struct cwiid_bdinfo **bdinfo, uint8_t flags)
56 {
57         inquiry_info *dev_list = NULL;
58         int max_inquiry;
59         int dev_count;
60         int sock = -1;
61         int bdinfo_count;
62         int i, j;
63         int err = 0;
64         int ret;
65
66         /* NULLify for the benefit of error handling */
67         *bdinfo = NULL;
68
69         /* If not given (=-1), get the first available Bluetooth interface */
70         if (dev_id == -1) {
71                 if ((dev_id = hci_get_route(NULL)) == -1) {
72                         cwiid_err(NULL, "No Bluetooth interface found");
73                         return -1;
74                 }
75         }
76
77         /* Get Bluetooth Device List */
78         if ((flags & BT_NO_WIIMOTE_FILTER) && (max_bdinfo != -1)) {
79                 max_inquiry = max_bdinfo;
80         }
81         else {
82                 max_inquiry = BT_MAX_INQUIRY;
83         }
84         if ((dev_count = hci_inquiry(dev_id, timeout, max_inquiry, NULL,
85                                      &dev_list, IREQ_CACHE_FLUSH)) == -1) {
86                 cwiid_err(NULL, "Bluetooth device inquiry error");
87                 err = 1;
88                 goto CODA;
89         }
90
91         if (dev_count == 0) {
92                 bdinfo_count = 0;
93                 goto CODA;
94         }
95
96         /* Open connection to Bluetooth Interface */
97         if ((sock = hci_open_dev(dev_id)) == -1) {
98                 cwiid_err(NULL, "Bluetooth interface open error");
99                 err = 1;
100                 goto CODA;
101         }
102
103         /* Allocate info list */
104         if (max_bdinfo == -1) {
105                 max_bdinfo = dev_count;
106         }
107         if ((*bdinfo = malloc(max_bdinfo * sizeof **bdinfo)) == NULL) {
108                 cwiid_err(NULL, "Memory allocation error (bdinfo array)");
109                 err = 1;
110                 goto CODA;
111         }
112
113         /* Copy dev_list to bdinfo */
114         for (bdinfo_count=i=0; (i < dev_count) && (bdinfo_count < max_bdinfo);
115              i++) {
116                 /* Filter by class */
117                 if (!(flags & BT_NO_WIIMOTE_FILTER) &&
118                   ((dev_list[i].dev_class[0] != WIIMOTE_CLASS_0) ||
119                    (dev_list[i].dev_class[1] != WIIMOTE_CLASS_1) ||
120                    (dev_list[i].dev_class[2] != WIIMOTE_CLASS_2))) {
121                         continue;
122                 }
123
124                 /* timeout (10000) in milliseconds */
125                 if (hci_read_remote_name(sock, &dev_list[i].bdaddr, BT_NAME_LEN,
126                                          (*bdinfo)[bdinfo_count].name, 10000)) {
127                         cwiid_err(NULL, "Bluetooth name read error");
128                         err = 1;
129                         goto CODA;
130                 }
131
132                 /* Filter by name */
133                 if (!(flags & BT_NO_WIIMOTE_FILTER) &&
134                   strncmp((*bdinfo)[bdinfo_count].name, WIIMOTE_NAME, BT_NAME_LEN)) {
135                         continue;
136                 }
137
138                 /* Passed filter, add to bdinfo */
139                 bacpy(&(*bdinfo)[bdinfo_count].bdaddr, &dev_list[i].bdaddr);
140                 for (j=0; j<3; j++) {
141                         (*bdinfo)[bdinfo_count].btclass[j] =
142                                     dev_list[i].dev_class[j];
143                 }
144                 bdinfo_count++;
145         }
146
147         if (bdinfo_count == 0) {
148                 free(*bdinfo);
149         }
150         else if (bdinfo_count < max_bdinfo) {
151                 if ((*bdinfo = realloc(*bdinfo, bdinfo_count * sizeof **bdinfo))
152                   == NULL) {
153                         cwiid_err(NULL, "Memory reallocation error (bdinfo array)");
154                         err = 1;
155                         goto CODA;
156                 }
157         }
158
159 CODA:
160         if (dev_list) free(dev_list);
161         if (sock != -1) hci_close_dev(sock);
162         if (err) {
163                 if (*bdinfo) free(*bdinfo);
164                 ret = -1;
165         }
166         else {
167                 ret = bdinfo_count;
168         }
169         return ret;
170 }
171
172 int cwiid_find_wiimote(bdaddr_t *bdaddr, int timeout)
173 {
174         struct cwiid_bdinfo *bdinfo;
175         int bdinfo_count;
176
177         if (timeout == -1) {
178                 while ((bdinfo_count = cwiid_get_bdinfo_array(-1, 2, 1, &bdinfo, 0))
179                        == 0);
180                 if (bdinfo_count == -1) {
181                         return -1;
182                 }
183         }
184         else {
185                 bdinfo_count = cwiid_get_bdinfo_array(-1, timeout, 1, &bdinfo, 0);
186                 if (bdinfo_count == -1) {
187                         return -1;
188                 }
189                 else if (bdinfo_count == 0) {
190                         cwiid_err(NULL, "No wiimotes found");
191                         return -1;
192                 }
193         }
194
195         bacpy(bdaddr, &bdinfo[0].bdaddr);
196         free(bdinfo);
197         return 0;
198 }
Note: See TracBrowser for help on using the browser.